summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2016-09-09 17:20:25 +0200
committerUlf Hermann <ulf.hermann@qt.io>2016-09-23 14:50:43 +0000
commitb83922861ce7214eb5a2b192ab040c3cc8a42a96 (patch)
tree91f9bae965e1d839cbedd10d15141fa5074669b9 /examples
parent68ec3971e9f826dc16c0c4638f586347af5389c3 (diff)
Add a simple FTP client example
With the provided FTP client you can fetch text files via anonymous FTP. Change-Id: I622264d72aac71492bf474dc1936917fdc78d499 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/scxml/ftpclient/ftpclient.pro19
-rw-r--r--examples/scxml/ftpclient/ftpcontrolchannel.cpp93
-rw-r--r--examples/scxml/ftpclient/ftpcontrolchannel.h94
-rw-r--r--examples/scxml/ftpclient/ftpdatachannel.cpp93
-rw-r--r--examples/scxml/ftpclient/ftpdatachannel.h91
-rw-r--r--examples/scxml/ftpclient/main.cpp135
-rw-r--r--examples/scxml/ftpclient/simpleftp.scxml102
-rw-r--r--examples/scxml/scxml.pro2
8 files changed, 629 insertions, 0 deletions
diff --git a/examples/scxml/ftpclient/ftpclient.pro b/examples/scxml/ftpclient/ftpclient.pro
new file mode 100644
index 0000000..7aa266e
--- /dev/null
+++ b/examples/scxml/ftpclient/ftpclient.pro
@@ -0,0 +1,19 @@
+QT = core scxml
+
+CONFIG += c++14
+TARGET = ftpclient
+
+TEMPLATE = app
+STATECHARTS += simpleftp.scxml
+
+SOURCES += \
+ main.cpp \
+ ftpcontrolchannel.cpp \
+ ftpdatachannel.cpp
+
+HEADERS += \
+ ftpcontrolchannel.h \
+ ftpdatachannel.h
+
+target.path = $$[QT_INSTALL_EXAMPLES]/scxml/ftpclient
+INSTALLS += target
diff --git a/examples/scxml/ftpclient/ftpcontrolchannel.cpp b/examples/scxml/ftpclient/ftpcontrolchannel.cpp
new file mode 100644
index 0000000..e90242d
--- /dev/null
+++ b/examples/scxml/ftpclient/ftpcontrolchannel.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ftpcontrolchannel.h"
+
+FtpControlChannel::FtpControlChannel(QObject *parent) : QObject(parent)
+{
+ connect(&m_socket, &QIODevice::readyRead, this, &FtpControlChannel::onReadyRead);
+ connect(&m_socket, &QAbstractSocket::disconnected, this, &FtpControlChannel::closed);
+ connect(&m_socket, &QAbstractSocket::connected, this, [this]() {
+ emit opened(m_socket.localAddress(), m_socket.localPort());
+ });
+}
+
+void FtpControlChannel::connectToServer(const QString &server)
+{
+ m_socket.connectToHost(server, 21);
+}
+
+void FtpControlChannel::command(const QString &command, const QString &params)
+{
+ QByteArray sendData = command.toUtf8();
+ if (!params.isEmpty())
+ sendData += " " + params.toUtf8();
+ m_socket.write(sendData + "\r\n");
+}
+
+void FtpControlChannel::onReadyRead()
+{
+ m_buffer.append(m_socket.readAll());
+ int rn = -1;
+ while ((rn = m_buffer.indexOf("\r\n")) != -1) {
+ QByteArray received = m_buffer.mid(0, rn);
+ m_buffer = m_buffer.mid(rn + 2);
+ int space = received.indexOf(' ');
+ if (space != -1) {
+ int code = received.mid(0, space).toInt();
+ if (code == 0)
+ emit info(QString::fromUtf8(received.mid(space + 1)));
+ else
+ emit reply(code, QString::fromUtf8(received.mid(space + 1)));
+ } else {
+ emit invalidReply(QString::fromUtf8(received));
+ }
+ }
+}
diff --git a/examples/scxml/ftpclient/ftpcontrolchannel.h b/examples/scxml/ftpclient/ftpcontrolchannel.h
new file mode 100644
index 0000000..a0cb95b
--- /dev/null
+++ b/examples/scxml/ftpclient/ftpcontrolchannel.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FTPCONTROLCHANNEL_H
+#define FTPCONTROLCHANNEL_H
+
+#include <QObject>
+#include <QTcpSocket>
+#include <QHostAddress>
+
+class FtpControlChannel : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FtpControlChannel(QObject *parent = 0);
+
+ // Connect to an FTP server
+ void connectToServer(const QString &server);
+
+ // Send a command to the server
+ void command(const QString &command, const QString &params);
+
+signals:
+
+ // Connection established. Local address and port are known.
+ void opened(const QHostAddress &localAddress, int localPort);
+
+ // Connection closed
+ void closed();
+
+ // Informational message
+ void info(const QString &info);
+
+ // Reply to a previously sent command
+ void reply(int code, const QString &parameters);
+
+ // Something is wrong
+ void invalidReply(const QString &reply);
+
+private:
+ void onReadyRead();
+
+ QTcpSocket m_socket;
+ QByteArray m_buffer;
+};
+
+#endif // FTPCONTROLCHANNEL_H
diff --git a/examples/scxml/ftpclient/ftpdatachannel.cpp b/examples/scxml/ftpclient/ftpdatachannel.cpp
new file mode 100644
index 0000000..b65e7f4
--- /dev/null
+++ b/examples/scxml/ftpclient/ftpdatachannel.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ftpdatachannel.h"
+
+FtpDataChannel::FtpDataChannel(QObject *parent) : QObject(parent)
+{
+ connect(&m_server, &QTcpServer::newConnection, this, [this]() {
+ m_socket.reset(m_server.nextPendingConnection());
+ connect(m_socket.data(), &QTcpSocket::readyRead, [this]() {
+ emit dataReceived(QString::fromUtf8(m_socket->readAll()));
+ });
+ });
+}
+
+void FtpDataChannel::listen(const QHostAddress &address)
+{
+ m_server.listen(address);
+}
+
+void FtpDataChannel::sendData(const QString &data)
+{
+ if (m_socket)
+ m_socket->write(data.toUtf8().replace("\n", "\r\n"));
+}
+
+void FtpDataChannel::close()
+{
+ if (m_socket)
+ m_socket->disconnectFromHost();
+}
+
+QString FtpDataChannel::portspec() const
+{
+ // Yes, this is a weird format, but say hello to FTP.
+ QString portSpec;
+ quint32 ipv4 = m_server.serverAddress().toIPv4Address();
+ quint16 port = m_server.serverPort();
+ portSpec += QString::number((ipv4 & 0xff000000) >> 24);
+ portSpec += ',' + QString::number((ipv4 & 0x00ff0000) >> 16);
+ portSpec += ',' + QString::number((ipv4 & 0x0000ff00) >> 8);
+ portSpec += ',' + QString::number(ipv4 & 0x000000ff);
+ portSpec += ',' + QString::number((port & 0xff00) >> 8);
+ portSpec += ',' + QString::number(port &0x00ff);
+ return portSpec;
+}
diff --git a/examples/scxml/ftpclient/ftpdatachannel.h b/examples/scxml/ftpclient/ftpdatachannel.h
new file mode 100644
index 0000000..4a46373
--- /dev/null
+++ b/examples/scxml/ftpclient/ftpdatachannel.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FTPDATACHANNEL_H
+#define FTPDATACHANNEL_H
+
+#include <QObject>
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <QScopedPointer>
+
+class FtpDataChannel : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FtpDataChannel(QObject *parent = 0);
+
+ // Listen on a local address.
+ void listen(const QHostAddress &address = QHostAddress::Any);
+
+ // Send data over the socket, as UTF-8 text.
+ void sendData(const QString &data);
+
+ // Close the connection.
+ void close();
+
+ // Retrieve the port specification to be announced on the control channel.
+ // Something like "a,b,c,d,xxx,yyy" where
+ // - a.b.c.d would be the IP address in decimal/dot notation and
+ // - xxx,yyy are the upper and lower 8 bits of the TCP port in decimal
+ // (This will only work if the local address we're listening on is actually meaningful)
+ QString portspec() const;
+
+signals:
+
+ // The FTP server has sent some data. We assume UTF-8 text for now.
+ void dataReceived(const QString &data);
+
+private:
+ QTcpServer m_server;
+ QScopedPointer<QTcpSocket> m_socket;
+};
+
+#endif // FTPDATACHANNEL_H
diff --git a/examples/scxml/ftpclient/main.cpp b/examples/scxml/ftpclient/main.cpp
new file mode 100644
index 0000000..46e7e51
--- /dev/null
+++ b/examples/scxml/ftpclient/main.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "simpleftp.h"
+#include "ftpcontrolchannel.h"
+#include "ftpdatachannel.h"
+#include <QCoreApplication>
+#include <iostream>
+
+struct Command {
+ QString cmd;
+ QString args;
+};
+
+int main(int argc, char *argv[])
+{
+#if defined(__cpp_return_type_deduction) && __cpp_return_type_deduction == 201304
+ if (argc != 3) {
+ qDebug() << "Usage: ftpclient <server> <file>";
+ return 1;
+ }
+
+ QString server = QString::fromLocal8Bit(argv[1]);
+ QString file = QString::fromLocal8Bit(argv[2]);
+
+ QCoreApplication app(argc, argv);
+ FtpClient ftpClient;
+ FtpDataChannel dataChannel;
+ FtpControlChannel controlChannel;
+
+ // Print all data retrieved from the server on the console as UTF-8 text.
+ QObject::connect(&dataChannel, &FtpDataChannel::dataReceived, [](const QString &data) {
+ std::cout << data.toUtf8().constData();
+ });
+
+ // Translate server replies into state machine events.
+ QObject::connect(&controlChannel, &FtpControlChannel::reply, &ftpClient,
+ [&ftpClient](int code, const QString &parameters) {
+ ftpClient.submitEvent(QString("reply.%1xx").arg(code / 100), parameters);
+ });
+
+ // Translate commands from the state machine into FTP control messages.
+ ftpClient.connectToEvent("submit.cmd", &controlChannel,
+ [&controlChannel](const QScxmlEvent &event) {
+ controlChannel.command(event.name().mid(11), event.data().toString());
+ });
+
+ // Commands to be sent
+ QList<Command> commands({
+ {"cmd.USER", "anonymous"},// login
+ {"cmd.PORT", ""}, // announce port for data connection, args added below.
+ {"cmd.RETR", file} // retrieve a file
+ });
+
+ // When entering "B" state, send the next command.
+ ftpClient.connectToState("B", QScxmlStateMachine::onEntry([&]() {
+ if (commands.isEmpty()) {
+ app.quit();
+ return;
+ }
+ Command command = commands.takeFirst();
+ qDebug() << "Posting command" << command.cmd << command.args;
+ ftpClient.submitEvent(command.cmd, command.args);
+ }));
+
+ // If the server asks for a password, send one.
+ ftpClient.connectToState("P", QScxmlStateMachine::onEntry([&ftpClient]() {
+ qDebug() << "Sending password";
+ ftpClient.submitEvent("cmd.PASS", QString());
+ }));
+
+ // Connect to our own local FTP server
+ controlChannel.connectToServer(server);
+ QObject::connect(&controlChannel, &FtpControlChannel::opened,
+ [&](const QHostAddress &address, int) {
+ dataChannel.listen(address);
+ commands[1].args = dataChannel.portspec();
+ ftpClient.start();
+ });
+
+ return app.exec();
+#else
+ qDebug() << "The ftpclient example uses the C++14 return type deduction feature and will only "
+ "work with compilers that support it.";
+ return 2;
+#endif
+}
diff --git a/examples/scxml/ftpclient/simpleftp.scxml b/examples/scxml/ftpclient/simpleftp.scxml
new file mode 100644
index 0000000..79eb7b9
--- /dev/null
+++ b/examples/scxml/ftpclient/simpleftp.scxml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" name="FtpClient"
+ datamodel="ecmascript">
+ <state id="G" initial="I">
+ <transition event="reply" target="E"/>
+ <transition event="cmd" target="F"/>
+
+ <state id="I">
+ <transition event="reply.2xx" target="S"/>
+ </state>
+
+ <state id="B">
+ <transition event="cmd.DELE cmd.CWD cmd.CDUP cmd.HELP cmd.NOOP cmd.QUIT cmd.SYST
+ cmd.STAT cmd.RMD cmd.MKD cmd.PWD cmd.PORT"
+ target="W.general"/>
+ <transition event="cmd.APPE cmd.LIST cmd.NLST cmd.REIN cmd.RETR cmd.STOR cmd.STOU"
+ target="W.1xx"/>
+ <transition event="cmd.USER" target="W.user"/>
+
+ <state id="S"/>
+ <state id="F"/>
+ </state>
+
+ <state id="W">
+ <onentry>
+ <send eventexpr="&quot;submit.&quot; + _event.name">
+ <content expr="_event.data"/>
+ </send>
+ </onentry>
+
+ <transition event="reply.2xx" target="S"/>
+ <transition event="reply.4xx reply.5xx" target="F"/>
+
+ <state id="W.1xx">
+ <transition event="reply.1xx" target="W.transfer"/>
+ </state>
+ <state id="W.transfer"/>
+ <state id="W.general"/>
+ <state id="W.user">
+ <transition event="reply.3xx" target="P"/>
+ </state>
+ <state id="W.login"/>
+ </state>
+
+ <state id="P">
+ <transition event="cmd.PASS" target="W.login"/>
+ </state>
+ </state>
+
+ <final id="E"/>
+</scxml>
diff --git a/examples/scxml/scxml.pro b/examples/scxml/scxml.pro
index 9da27ce..c8da669 100644
--- a/examples/scxml/scxml.pro
+++ b/examples/scxml/scxml.pro
@@ -22,4 +22,6 @@ qtHaveModule(qml) {
SUBDIRS += invoke-static
SUBDIRS += invoke-dynamic
}
+
+SUBDIRS += ftpclient
}