aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppFileShare.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/QXmppFileShare.cpp')
-rw-r--r--src/base/QXmppFileShare.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/base/QXmppFileShare.cpp b/src/base/QXmppFileShare.cpp
new file mode 100644
index 00000000..8d73dbe5
--- /dev/null
+++ b/src/base/QXmppFileShare.cpp
@@ -0,0 +1,151 @@
+// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "QXmppFileShare.h"
+
+#include "QXmppConstants_p.h"
+#include "QXmppFileMetadata.h"
+
+#include <optional>
+
+#include <QDomElement>
+#include <QUrl>
+#include <QXmlStreamWriter>
+
+using Disposition = QXmppFileShare::Disposition;
+
+static std::optional<Disposition> dispositionFromString(const QString &str)
+{
+ if (str == "inline") {
+ return Disposition::Inline;
+ }
+ if (str == "attachment") {
+ return Disposition::Attachment;
+ }
+ return {};
+}
+
+static QString dispositionToString(Disposition value)
+{
+ switch (value) {
+ case Disposition::Inline:
+ return QStringLiteral("inline");
+ case Disposition::Attachment:
+ return QStringLiteral("attachment");
+ }
+ Q_UNREACHABLE();
+}
+
+/// \cond
+class QXmppFileSharePrivate : public QSharedData
+{
+public:
+ QXmppFileMetadata metadata;
+ QVector<QUrl> httpSources;
+ QXmppFileShare::Disposition disposition = Disposition::Inline;
+};
+/// \endcond
+
+///
+/// \class QXmppFileSharePrivate
+///
+/// File sharing element from \xep{0447, Stateless file sharing}. Contains
+/// metadata and source URLs.
+///
+/// \note jinglepub references are currently missing
+///
+/// \since QXmpp 1.5
+///
+
+/// Default constructor
+QXmppFileShare::QXmppFileShare()
+ : d(new QXmppFileSharePrivate)
+{
+}
+
+QXmppFileShare::QXmppFileShare(const QXmppFileShare &) = default;
+QXmppFileShare::QXmppFileShare(QXmppFileShare &&) noexcept = default;
+QXmppFileShare::~QXmppFileShare() = default;
+QXmppFileShare &QXmppFileShare::operator=(const QXmppFileShare &) = default;
+QXmppFileShare &QXmppFileShare::operator=(QXmppFileShare &&) noexcept = default;
+
+/// Returns the disposition setting for this file.
+QXmppFileShare::Disposition QXmppFileShare::disposition() const
+{
+ return d->disposition;
+}
+
+/// Sets the disposition setting for this file.
+void QXmppFileShare::setDisposition(Disposition disp)
+{
+ d->disposition = disp;
+}
+
+const QXmppFileMetadata &QXmppFileShare::metadata() const
+{
+ return d->metadata;
+}
+
+void QXmppFileShare::setMetadata(const QXmppFileMetadata &metadata)
+{
+ d->metadata = metadata;
+}
+
+const QVector<QUrl> &QXmppFileShare::httpSources() const
+{
+ return d->httpSources;
+}
+
+void QXmppFileShare::setHttpSources(const QVector<QUrl> &newHttpSources)
+{
+ d->httpSources = newHttpSources;
+}
+
+/// \cond
+bool QXmppFileShare::parse(const QDomElement &el)
+{
+ if (el.tagName() == "file-sharing" && el.namespaceURI() == ns_sfs) {
+ // disposition
+ d->disposition = dispositionFromString(el.attribute("disposition"))
+ .value_or(Disposition::Inline);
+
+ // file metadata
+ auto fileEl = el.firstChildElement("file");
+ d->metadata = QXmppFileMetadata();
+ if (!d->metadata.parse(fileEl)) {
+ return false;
+ }
+
+ // sources:
+ // expect that there's only one sources element with the correct namespace
+ auto sources = el.firstChildElement("sources");
+ for (auto urlEl = sources.firstChildElement("url-data");
+ !urlEl.isNull();
+ urlEl = urlEl.nextSiblingElement("url-data")) {
+ if (urlEl.namespaceURI() == "http://jabber.org/protocol/url-data") {
+ d->httpSources.append(QUrl(urlEl.attribute("target")));
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+void QXmppFileShare::toXml(QXmlStreamWriter *writer) const
+{
+ writer->writeStartElement("file-sharing");
+ writer->writeDefaultNamespace(ns_sfs);
+ writer->writeAttribute("disposition", dispositionToString(d->disposition));
+ d->metadata.toXml(writer);
+ writer->writeStartElement("sources");
+ for (const auto &source : d->httpSources) {
+ writer->writeStartElement("url-data");
+ writer->writeDefaultNamespace(ns_url_data);
+ writer->writeAttribute("target", source.toString());
+ writer->writeEndElement();
+ }
+ writer->writeEndElement();
+ writer->writeEndElement();
+}
+/// \endcond