diff options
Diffstat (limited to 'src/plugins/position/nmea')
-rw-r--r-- | src/plugins/position/nmea/CMakeLists.txt | 22 | ||||
-rw-r--r-- | src/plugins/position/nmea/nmea.pro | 16 | ||||
-rw-r--r-- | src/plugins/position/nmea/plugin.json | 9 | ||||
-rw-r--r-- | src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp | 505 | ||||
-rw-r--r-- | src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h | 63 | ||||
-rw-r--r-- | src/plugins/position/nmea/qiopipe.cpp | 207 | ||||
-rw-r--r-- | src/plugins/position/nmea/qiopipe_p.h | 114 |
7 files changed, 0 insertions, 936 deletions
diff --git a/src/plugins/position/nmea/CMakeLists.txt b/src/plugins/position/nmea/CMakeLists.txt deleted file mode 100644 index 73c5a3b1..00000000 --- a/src/plugins/position/nmea/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Generated from nmea.pro. - -##################################################################### -## QGeoPositionInfoSourceFactoryNmea Plugin: -##################################################################### - -qt_internal_add_plugin(QGeoPositionInfoSourceFactoryNmeaPlugin - OUTPUT_NAME qtposition_nmea - CLASS_NAME QGeoPositionInfoSourceFactoryNmea - PLUGIN_TYPE position - SOURCES - qgeopositioninfosourcefactory_nmea.cpp qgeopositioninfosourcefactory_nmea.h - qiopipe.cpp qiopipe_p.h - LIBRARIES - Qt::CorePrivate - Qt::Positioning - Qt::SerialPort - Qt::Network -) - -#### Keys ignored in scope 1:.:.:serialnmea.pro:<TRUE>: -# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/nmea/nmea.pro b/src/plugins/position/nmea/nmea.pro deleted file mode 100644 index f52d8812..00000000 --- a/src/plugins/position/nmea/nmea.pro +++ /dev/null @@ -1,16 +0,0 @@ -TARGET = qtposition_nmea - -QT = core-private positioning-private serialport - -HEADERS += \ - qgeopositioninfosourcefactory_nmea.h qiopipe_p.h - -SOURCES += \ - qgeopositioninfosourcefactory_nmea.cpp qiopipe.cpp - -OTHER_FILES += \ - plugin.json - -PLUGIN_TYPE = position -PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryNmea -load(qt_plugin) diff --git a/src/plugins/position/nmea/plugin.json b/src/plugins/position/nmea/plugin.json deleted file mode 100644 index 15d22f1f..00000000 --- a/src/plugins/position/nmea/plugin.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Keys": ["nmea"], - "Provider": "nmea", - "Position": true, - "Satellite": false, - "Monitor" : false, - "Priority": 1000, - "Testable": false -} diff --git a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp deleted file mode 100644 index 15460062..00000000 --- a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp +++ /dev/null @@ -1,505 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning 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$ -** -****************************************************************************/ - -#include "qgeopositioninfosourcefactory_nmea.h" -#include <QtPositioning/QNmeaPositionInfoSource> -#include <QtPositioning/QNmeaSatelliteInfoSource> -#include <QtSerialPort/QSerialPort> -#include <QtSerialPort/QSerialPortInfo> -#include <QtNetwork/QTcpSocket> -#include <QLoggingCategory> -#include <QSet> -#include <QUrl> -#include <QFile> -#include <QSharedPointer> -#include "qiopipe_p.h" - -Q_LOGGING_CATEGORY(lcNmea, "qt.positioning.nmea") - -QT_BEGIN_NAMESPACE - -static const auto sourceParameterName = QStringLiteral("nmea.source"); -static const auto socketScheme = QStringLiteral("socket:"); -static const auto serialScheme = QStringLiteral("serial:"); - -// This class is used only for SerialPort devices, because we can't open the -// same serial port twice. -// In case of files and sockets it's easier to explicitly create a QIODevice for -// each new instance of Nmea*InfoSource. -// Also QFile can't be directly used with QIOPipe, because QFile is not a -// sequential device. -// TcpSocket could be used with QIOPipe, but it complicates error handling -// dramatically, as we would need to somehow forward socket errors through -// QIOPipes to the clients. -class IODeviceContainer -{ -public: - IODeviceContainer() {} - IODeviceContainer(IODeviceContainer const&) = delete; - void operator=(IODeviceContainer const&) = delete; - - QSharedPointer<QIOPipe> serial(const QString &portName) - { - if (m_serialPorts.contains(portName)) { - m_serialPorts[portName].refs++; - QIOPipe *endPipe = new QIOPipe(m_serialPorts[portName].proxy); - m_serialPorts[portName].proxy->addChildPipe(endPipe); - return QSharedPointer<QIOPipe>(endPipe); - } - IODevice device; - QSerialPort *port = new QSerialPort(portName); - port->setBaudRate(4800); - qCDebug(lcNmea) << "Opening serial port" << portName; - if (!port->open(QIODevice::ReadOnly)) { - qWarning("nmea: Failed to open %s", qPrintable(portName)); - delete port; - return {}; - } - qCDebug(lcNmea) << "Opened successfully"; - device.device = port; - device.refs = 1; - device.proxy = new QIOPipe(port, QIOPipe::ProxyPipe); - m_serialPorts[portName] = device; - QIOPipe *endPipe = new QIOPipe(device.proxy); - device.proxy->addChildPipe(endPipe); - return QSharedPointer<QIOPipe>(endPipe); - } - - void releaseSerial(const QString &portName, QSharedPointer<QIOPipe> &pipe) - { - if (!m_serialPorts.contains(portName)) - return; - - pipe.clear(); // make sure to release the pipe returned by getSerial, or else, if there are still refs, data will be leaked through it - IODevice &device = m_serialPorts[portName]; - if (device.refs > 1) { - device.refs--; - return; - } - - IODevice taken = m_serialPorts.take(portName); - taken.device->deleteLater(); - } - -private: - - struct IODevice { - QIODevice *device = nullptr; - QIOPipe *proxy = nullptr; // adding client pipes as children of proxy - // allows to dynamically add clients to one device. - unsigned int refs = 1; - }; - - QMap<QString, IODevice> m_serialPorts; -}; - -Q_GLOBAL_STATIC(IODeviceContainer, deviceContainer) - -// We use a string prefix to distinguish between the different data sources. -// "socket:" means that we use a socket connection -// "serial:" means that we use a serial port connection -// "file:///", "qrc:///" and just plain strings mean that we try to use local -// file. -// Note: if we do not specify anything, or specify "serial:" without specifying -// the port name, then we will try to search for a well-known serial port -// device. -class NmeaSource : public QNmeaPositionInfoSource -{ - Q_OBJECT -public: - NmeaSource(QObject *parent, const QVariantMap ¶meters); - NmeaSource(QObject *parent, const QString &fileName); - ~NmeaSource() override; - bool isValid() const - { - return !m_dataSource.isNull() || !m_fileSource.isNull() || !m_socket.isNull(); - } - -private slots: - void onSocketError(QAbstractSocket::SocketError error); - -private: - void parseSourceParameter(const QString &source); - void addSerialDevice(const QString &requestedPort); - void setFileName(const QString &fileName); - void connectSocket(const QString &source); - - QSharedPointer<QIOPipe> m_dataSource; - QScopedPointer<QFile> m_fileSource; - QScopedPointer<QTcpSocket> m_socket; - QString m_sourceName; -}; - -NmeaSource::NmeaSource(QObject *parent, const QVariantMap ¶meters) - : QNmeaPositionInfoSource(RealTimeMode, parent) -{ - const QString source = parameters.value(sourceParameterName).toString(); - parseSourceParameter(source); -} - -NmeaSource::NmeaSource(QObject *parent, const QString &fileName) - : QNmeaPositionInfoSource(SimulationMode, parent) -{ - setFileName(fileName); -} - -NmeaSource::~NmeaSource() -{ - deviceContainer->releaseSerial(m_sourceName, m_dataSource); -} - -void NmeaSource::onSocketError(QAbstractSocket::SocketError error) -{ - m_socket->close(); - - switch (error) { - case QAbstractSocket::UnknownSocketError: - setError(QGeoPositionInfoSource::UnknownSourceError); - break; - case QAbstractSocket::SocketAccessError: - setError(QGeoPositionInfoSource::AccessError); - break; - case QAbstractSocket::RemoteHostClosedError: - setError(QGeoPositionInfoSource::ClosedError); - break; - default: - qWarning() << "Connection failed! QAbstractSocket::SocketError" << error; - // TODO - introduce new type of error. TransportError? - setError(QGeoPositionInfoSource::UnknownSourceError); - break; - } -} - -void NmeaSource::parseSourceParameter(const QString &source) -{ - if (source.startsWith(socketScheme)) { - // This is a socket - connectSocket(source); - } else { - // Last chance - this can be serial device. - // Note: File is handled in a separate case. - addSerialDevice(source); - } -} - -static QString tryFindSerialDevice(const QString &requestedPort) -{ - QString portName; - if (requestedPort.isEmpty()) { - const QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts(); - qCDebug(lcNmea) << "Found" << ports.count() << "serial ports"; - if (ports.isEmpty()) { - qWarning("nmea: No serial ports found"); - return portName; - } - - // Try to find a well-known device. - QSet<int> supportedDevices; - supportedDevices << 0x67b; // GlobalSat (BU-353S4 and probably others) - supportedDevices << 0xe8d; // Qstarz MTK II - for (const QSerialPortInfo& port : ports) { - if (port.hasVendorIdentifier() && supportedDevices.contains(port.vendorIdentifier())) { - portName = port.portName(); - break; - } - } - - if (portName.isEmpty()) { - qWarning("nmea: No known GPS device found."); - } - } else { - portName = requestedPort; - if (portName.startsWith(serialScheme)) - portName.remove(0, 7); - } - return portName; -} - -void NmeaSource::addSerialDevice(const QString &requestedPort) -{ - m_sourceName = tryFindSerialDevice(requestedPort); - if (m_sourceName.isEmpty()) - return; - - m_dataSource = deviceContainer->serial(m_sourceName); - if (!m_dataSource) - return; - - setDevice(m_dataSource.data()); -} - -void NmeaSource::setFileName(const QString &fileName) -{ - m_sourceName = fileName; - - m_fileSource.reset(new QFile(fileName)); - qCDebug(lcNmea) << "Opening file" << fileName; - if (!m_fileSource->open(QIODevice::ReadOnly)) { - qWarning("nmea: failed to open file %s", qPrintable(fileName)); - m_fileSource.reset(); - } - - if (!m_fileSource) - return; - - qCDebug(lcNmea) << "Opened successfully"; - - setDevice(m_fileSource.data()); -} - -void NmeaSource::connectSocket(const QString &source) -{ - const QUrl url(source); - const QString host = url.host(); - const int port = url.port(); - if (!host.isEmpty() && (port > 0)) { - m_socket.reset(new QTcpSocket); - // no need to explicitly connect to connected() signal - connect(m_socket.get(), &QTcpSocket::errorOccurred, this, &NmeaSource::onSocketError); - m_socket->connectToHost(host, port, QTcpSocket::ReadOnly); - m_sourceName = source; - - setDevice(m_socket.data()); - } else { - qWarning("nmea: incorrect socket parameters %s:%d", qPrintable(host), port); - } -} - -class NmeaSatelliteSource : public QNmeaSatelliteInfoSource -{ - Q_OBJECT -public: - NmeaSatelliteSource(QObject *parent, const QVariantMap ¶meters); - NmeaSatelliteSource(QObject *parent, const QString &fileName, const QVariantMap ¶meters); - ~NmeaSatelliteSource(); - - bool isValid() const { return !m_port.isNull() || !m_file.isNull() || !m_socket.isNull(); } - -private slots: - void onSocketError(QAbstractSocket::SocketError error); - -private: - void parseRealtimeSource(const QString &source); - void parseSimulationSource(const QString &localFileName); - - QSharedPointer<QIOPipe> m_port; - QScopedPointer<QFile> m_file; - QScopedPointer<QTcpSocket> m_socket; - QString m_sourceName; -}; - -NmeaSatelliteSource::NmeaSatelliteSource(QObject *parent, const QVariantMap ¶meters) - : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode, parent) -{ - const QString source = parameters.value(sourceParameterName).toString(); - parseRealtimeSource(source); -} - -// We can use a QNmeaSatelliteInfoSource::SimulationUpdateInterval parameter to -// set the file read frequency in simulation mode. We use setBackendProperty() -// for it. The value can't be smaller than minimumUpdateInterval(). -// This check is done on the QNmeaSatelliteInfoSource level -NmeaSatelliteSource::NmeaSatelliteSource(QObject *parent, const QString &fileName, - const QVariantMap ¶meters) - : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::SimulationMode, parent) -{ - bool ok = false; - const int interval = - parameters.value(QNmeaSatelliteInfoSource::SimulationUpdateInterval).toInt(&ok); - if (ok) - setBackendProperty(QNmeaSatelliteInfoSource::SimulationUpdateInterval, interval); - parseSimulationSource(fileName); -} - -NmeaSatelliteSource::~NmeaSatelliteSource() -{ - deviceContainer->releaseSerial(m_sourceName, m_port); -} - -void NmeaSatelliteSource::onSocketError(QAbstractSocket::SocketError error) -{ - m_socket->close(); - - switch (error) { - case QAbstractSocket::UnknownSocketError: - setError(QGeoSatelliteInfoSource::UnknownSourceError); - break; - case QAbstractSocket::SocketAccessError: - setError(QGeoSatelliteInfoSource::AccessError); - break; - case QAbstractSocket::RemoteHostClosedError: - setError(QGeoSatelliteInfoSource::ClosedError); - break; - default: - qWarning() << "Connection failed! QAbstractSocket::SocketError" << error; - // TODO - introduce new type of error. TransportError? - setError(QGeoSatelliteInfoSource::UnknownSourceError); - break; - } -} - -void NmeaSatelliteSource::parseRealtimeSource(const QString &source) -{ - if (source.startsWith(socketScheme)) { - // This is a socket. - const QUrl url(source); - const QString host = url.host(); - const int port = url.port(); - if (!host.isEmpty() && (port > 0)) { - m_socket.reset(new QTcpSocket); - // no need to explicitly connect to connected() signal - connect(m_socket.get(), &QTcpSocket::errorOccurred, - this, &NmeaSatelliteSource::onSocketError); - m_socket->connectToHost(host, port, QTcpSocket::ReadOnly); - m_sourceName = source; - - setDevice(m_socket.data()); - } else { - qWarning("nmea: incorrect socket parameters %s:%d", qPrintable(host), port); - } - } else { - // Last chance - this can be serial device. - m_sourceName = tryFindSerialDevice(source); - if (m_sourceName.isEmpty()) - return; - - m_port = deviceContainer->serial(m_sourceName); - if (!m_port) - return; - - setDevice(m_port.data()); - } -} - -void NmeaSatelliteSource::parseSimulationSource(const QString &localFileName) -{ - // This is a text file. - m_sourceName = localFileName; - - qCDebug(lcNmea) << "Opening file" << localFileName; - m_file.reset(new QFile(localFileName)); - if (!m_file->open(QIODevice::ReadOnly)) { - qWarning("nmea: failed to open file %s", qPrintable(localFileName)); - m_file.reset(); - return; - } - qCDebug(lcNmea) << "Opened successfully"; - - setDevice(m_file.data()); -} - -/*! - \internal - Returns a local file name if \a source represents it. - The returned value can be different from \a source, as the method tries to - modify the path -*/ -static QString checkSourceIsFile(const QString &source) -{ - if (source.isEmpty()) - return QString(); - - QString localFileName = source; - - if (!QFile::exists(localFileName)) { - if (localFileName.startsWith(QStringLiteral("qrc:///"))) - localFileName.remove(0, 7); - else if (localFileName.startsWith(QStringLiteral("file:///"))) - localFileName.remove(0, 7); - else if (localFileName.startsWith(QStringLiteral("qrc:/"))) - localFileName.remove(0, 5); - - if (!QFile::exists(localFileName) && localFileName.startsWith(QLatin1Char('/'))) - localFileName.remove(0, 1); - } - if (!QFile::exists(localFileName)) - localFileName.prepend(QLatin1Char(':')); - - const bool isLocalFile = QFile::exists(localFileName); - return isLocalFile ? localFileName : QString(); -} - -/*! - \internal - Returns a local file name if file exists, or an empty string otherwise -*/ -static QString extractLocalFileName(const QVariantMap ¶meters) -{ - QString localFileName = parameters.value(sourceParameterName).toString(); - return checkSourceIsFile(localFileName); -} - -QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryNmea::positionInfoSource(QObject *parent, const QVariantMap ¶meters) -{ - std::unique_ptr<NmeaSource> src = nullptr; - - const QString localFileName = extractLocalFileName(parameters); - if (localFileName.isEmpty()) - src = std::make_unique<NmeaSource>(parent, parameters); // use RealTimeMode - else - src = std::make_unique<NmeaSource>(parent, localFileName); // use SimulationMode - - return (src && src->isValid()) ? src.release() : nullptr; -} - -QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryNmea::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) -{ - std::unique_ptr<NmeaSatelliteSource> src = nullptr; - - const QString localFileName = extractLocalFileName(parameters); - if (localFileName.isEmpty()) { - // use RealTimeMode - src = std::make_unique<NmeaSatelliteSource>(parent, parameters); - } else { - // use SimulationMode - src = std::make_unique<NmeaSatelliteSource>(parent, localFileName, parameters); - } - return (src && src->isValid()) ? src.release() : nullptr; -} - -QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryNmea::areaMonitor(QObject *parent, const QVariantMap ¶meters) -{ - Q_UNUSED(parent); - Q_UNUSED(parameters); - return nullptr; -} - -QT_END_NAMESPACE - -#include "qgeopositioninfosourcefactory_nmea.moc" diff --git a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h deleted file mode 100644 index d7ac98aa..00000000 --- a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning 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 QGEOPOSITIONINFOSOURCEFACTORY_NMEA_H -#define QGEOPOSITIONINFOSOURCEFACTORY_NMEA_H - -#include <QObject> -#include <QtPositioning/QGeoPositionInfoSourceFactory> - -QT_BEGIN_NAMESPACE - -class QGeoPositionInfoSourceFactoryNmea : public QObject, public QGeoPositionInfoSourceFactory -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" - FILE "plugin.json") - Q_INTERFACES(QGeoPositionInfoSourceFactory) - -public: - QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; - QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; - QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/position/nmea/qiopipe.cpp b/src/plugins/position/nmea/qiopipe.cpp deleted file mode 100644 index 75cd923c..00000000 --- a/src/plugins/position/nmea/qiopipe.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtLocation 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$ -** -****************************************************************************/ - -#include "qiopipe_p.h" -#include <QtCore/qmetaobject.h> -#include <QDebug> - -QT_BEGIN_NAMESPACE - -/* - proxying means do *not* emit readyRead, and instead pump data - into child pipes directly in a zero-copy fashion. -*/ -QIOPipePrivate::QIOPipePrivate(QIODevice *iodevice, bool proxying) - : m_proxying(proxying), source(iodevice) -{ -} - -QIOPipePrivate::~QIOPipePrivate() -{ -} - -void QIOPipePrivate::initialize() -{ - const QIOPipe *parentPipe = qobject_cast<QIOPipe *>(source); - if (parentPipe && parentPipe->d_func()->m_proxying) // with proxying parent, - return; // don't do anything - - // read available data, does not emit. - readAvailableData(); - // connect readyRead to onReadyRead - QObjectPrivate::connect(source, &QIODevice::readyRead, this, &QIOPipePrivate::_q_onReadyRead); -} - -bool QIOPipePrivate::readAvailableData() { - if (!source) - return false; - QByteArray ba = source->readAll(); - if (!ba.size()) - return false; - - pumpData(ba); - return true; -} - -void QIOPipePrivate::pumpData(const QByteArray &ba) -{ - if (m_proxying) { - QList<int> toRemove; - for (int i = 0; i < childPipes.size(); ++i) { - const QPointer<QIOPipe> &cp = childPipes.at(i); - if (!cp) { - toRemove.append(i); - continue; - } - QIOPipePrivate *cpp = cp->d_func(); - cpp->pushData(ba); - } - for (int i = toRemove.size() - 1; i >= 0; --i) { - childPipes.remove(i); - } - } else { - for (int i = 0; i < readBuffers.size(); i++) - readBuffers[i].append(ba); - } -} - -void QIOPipePrivate::pushData(const QByteArray &ba) -{ - Q_Q(QIOPipe); - if (!ba.size()) - return; - - pumpData(ba); - if (!m_proxying) - emit q->readyRead(); -} - -void QIOPipePrivate::_q_onReadyRead() -{ - Q_Q(QIOPipe); - if (readAvailableData() && !m_proxying) - emit q->readyRead(); -} - -void QIOPipePrivate::addChildPipe(QIOPipe *childPipe) -{ - if (childPipes.contains(childPipe)) - return; - childPipes.append(childPipe); -} - -void QIOPipePrivate::removeChildPipe(QIOPipe *childPipe) -{ - childPipes.removeOne(childPipe); -} - -QIOPipe::QIOPipe(QIODevice *parent, Mode mode) - : QIODevice(*new QIOPipePrivate(parent, mode == ProxyPipe), parent) -{ - this->d_func()->initialize(); - if (!parent->isOpen() && !parent->open(QIODevice::ReadOnly)) { - qWarning() << "QIOPipe: Failed to open " << parent; - return; - } - open(ReadOnly); -} - -QIOPipe::~QIOPipe() -{ - -} - -bool QIOPipe::open(QIODevice::OpenMode mode) -{ - if (isOpen()) - return true; - - static const OpenMode supportedOpenMode = ReadOnly; // Currently limit it to read only - if (!(mode & supportedOpenMode)) { - qFatal("Unsupported open mode"); - return false; - } - - return QIODevice::open(mode); -} - -bool QIOPipe::isSequential() const -{ - return true; -} - -void QIOPipe::setReadChannelCount(int count) -{ - Q_D(QIOPipe); - d->setReadChannelCount(qMax(count, 1)); -} - -void QIOPipe::addChildPipe(QIOPipe *childPipe) -{ - Q_D(QIOPipe); - d->addChildPipe(childPipe); -} - -/*! - \reimp - - \omit - This function does not really read anything, as we use QIODevicePrivate's - buffer. The buffer will be read inside of QIODevice before this - method will be called. - See QIODevicePrivate::read, buffer.read(data, maxSize). - \endomit -*/ -qint64 QIOPipe::readData(char *data, qint64 maxlen) -{ - Q_UNUSED(data); - Q_UNUSED(maxlen); - - // return 0 indicating there may be more data in the future - // Returning -1 means no more data in the future (end of stream). - return qint64(0); -} - -qint64 QIOPipe::writeData(const char * /*data*/, qint64 /*len*/) -{ - qFatal("QIOPipe is a read-only device"); - return qint64(0); -} - -QT_END_NAMESPACE diff --git a/src/plugins/position/nmea/qiopipe_p.h b/src/plugins/position/nmea/qiopipe_p.h deleted file mode 100644 index dd83588a..00000000 --- a/src/plugins/position/nmea/qiopipe_p.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtLocation 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 QIOPIPE_P_H -#define QIOPIPE_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 <QtCore/qiodevice.h> -#include <QtCore/qbytearray.h> -#include <QtCore/private/qiodevice_p.h> - -QT_BEGIN_NAMESPACE - -class QObject; -class QIOPipePrivate; - -class QIOPipe : public QIODevice -{ - Q_OBJECT - -public: - enum Mode { - EndPipe = 0x0000, - ProxyPipe = 0x0001 - }; - - explicit QIOPipe(QIODevice *parent, Mode mode = EndPipe); - ~QIOPipe() override; - - bool open(OpenMode openMode) override; - bool isSequential() const override; - void setReadChannelCount(int count); - void addChildPipe(QIOPipe *childPipe); - -protected: - qint64 readData(char *data, qint64 maxlen) override; - qint64 writeData(const char *data, qint64 len) override; - -private: - Q_DECLARE_PRIVATE(QIOPipe) - Q_DISABLE_COPY(QIOPipe) -}; - -class QIOPipePrivate : public QIODevicePrivate -{ - Q_DECLARE_PUBLIC(QIOPipe) - -public: - explicit QIOPipePrivate(QIODevice *iodevice, bool proxying); - ~QIOPipePrivate() override; - - void initialize(); - bool readAvailableData(); - void pumpData(const QByteArray &ba); - void pushData(const QByteArray &ba); - void _q_onReadyRead(); - void addChildPipe(QIOPipe *childPipe); - void removeChildPipe(QIOPipe *childPipe); - - bool m_proxying = false; - QPointer<QIODevice> source; - QList<QPointer<QIOPipe>> childPipes; -}; - -QT_END_NAMESPACE - -#endif // QIOPIPE_P_H - |