// SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert // // SPDX-License-Identifier: LGPL-2.1-or-later #include "QXmppFileMetadata.h" #include "QXmppConstants_p.h" #include "QXmppHash.h" #include "QXmppThumbnail.h" #include "QXmppUtils.h" #include #include #include #include #include class QXmppFileMetadataPrivate : public QSharedData { public: std::optional date; std::optional desc; QVector hashes; std::optional height; std::optional length; std::optional mediaType; std::optional name; std::optional size; QVector thumbnails; std::optional width; }; /// /// \class QXmppFileMetadata /// /// File metadata from \xep{0446, File metadata element}. /// /// \since QXmpp 1.5 /// /// /// \brief Creates a QXmppFileMetadata object from information from QFileInfo. /// /// Sets the filename, file size, media type and the last modification date. /// QXmppFileMetadata QXmppFileMetadata::fromFileInfo(const QFileInfo &info) { QXmppFileMetadata metadata; metadata.setFilename(info.fileName()); metadata.setSize(info.size()); metadata.setMediaType(QMimeDatabase().mimeTypeForFile(info)); metadata.setLastModified(info.lastModified()); return metadata; } QXmppFileMetadata::QXmppFileMetadata() : d(new QXmppFileMetadataPrivate()) { } QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppFileMetadata) /// \cond QVector allChildElements(const QDomElement &el, const QString &name) { QVector out; for (auto childEl = el.firstChildElement(name); !childEl.isNull(); childEl = childEl.nextSiblingElement(name)) { out.push_back(childEl); } return out; } template QVector> forAllChildElements(const QDomElement &el, const QString &name, Func func) { auto elements = allChildElements(el, name); QVector> out; std::transform(elements.begin(), elements.end(), std::back_inserter(out), func); return out; } bool QXmppFileMetadata::parse(const QDomElement &el) { if (el.isNull()) { return false; } if (auto dateEl = el.firstChildElement("date"); !dateEl.isNull()) { d->date = QXmppUtils::datetimeFromString(dateEl.text()); } if (auto descEl = el.firstChildElement("desc"); !descEl.isNull()) { d->desc = descEl.text(); } d->hashes = forAllChildElements(el, "hash", [](const auto &el) { QXmppHash hash; hash.parse(el); return hash; }); if (auto heightEl = el.firstChildElement("height"); !heightEl.isNull()) { d->height = el.firstChildElement("height").text().toUInt(); } if (auto lengthEl = el.firstChildElement("length"); !lengthEl.isNull()) { d->length = lengthEl.text().toUInt(); } if (auto mediaTypeEl = el.firstChildElement("media-type"); !mediaTypeEl.isNull()) { d->mediaType = QMimeDatabase().mimeTypeForName(mediaTypeEl.text()); } if (auto nameEl = el.firstChildElement("name"); !nameEl.isNull()) { d->name = nameEl.text(); } if (auto sizeEl = el.firstChildElement("size"); !sizeEl.isNull()) { d->size = sizeEl.text().toULong(); } for (auto thumbEl = el.firstChildElement("thumbnail"); !thumbEl.isNull(); thumbEl = thumbEl.nextSiblingElement("thumbnail")) { QXmppThumbnail thumbnail; if (thumbnail.parse(thumbEl)) { d->thumbnails.append(std::move(thumbnail)); } } if (auto widthEl = el.firstChildElement("width"); !widthEl.isNull()) { d->width = widthEl.text().toUInt(); } return true; } void QXmppFileMetadata::toXml(QXmlStreamWriter *writer) const { writer->writeStartElement("file"); writer->writeDefaultNamespace(ns_file_metadata); if (d->date) { writer->writeTextElement("date", QXmppUtils::datetimeToString(*d->date)); } if (d->desc) { writer->writeTextElement("desc", *d->desc); } for (const auto &hash : d->hashes) { hash.toXml(writer); } if (d->height) { writer->writeTextElement("height", QString::number(*d->height)); } if (d->length) { writer->writeTextElement("length", QString::number(*d->length)); } if (d->mediaType) { writer->writeTextElement("media-type", d->mediaType->name()); } if (d->name) { writer->writeTextElement("name", *d->name); } if (d->size) { writer->writeTextElement("size", QString::number(*d->size)); } for (const auto &thumbnail : d->thumbnails) { thumbnail.toXml(writer); } if (d->width) { writer->writeTextElement("width", QString::number(*d->width)); } writer->writeEndElement(); } /// \endcond /// Returns when the file was last modified const std::optional &QXmppFileMetadata::lastModified() const { return d->date; } /// Sets when the file was last modified void QXmppFileMetadata::setLastModified(const std::optional &date) { d->date = date; } /// Returns the description of the file const std::optional &QXmppFileMetadata::description() const { return d->desc; } /// Sets the description of the file void QXmppFileMetadata::setDescription(const std::optional &description) { d->desc = description; } /// Returns the hashes of the file const QVector &QXmppFileMetadata::hashes() const { return d->hashes; } /// Sets the hashes of the file void QXmppFileMetadata::setHashes(const QVector &hashes) { d->hashes = hashes; } /// Returns the height of the image std::optional QXmppFileMetadata::height() const { return d->height; } /// Sets the height of the image void QXmppFileMetadata::setHeight(std::optional height) { d->height = height; } /// Returns the length of a video or audio file std::optional QXmppFileMetadata::length() const { return d->length; } /// Sets the length of a video or audio file void QXmppFileMetadata::setLength(std::optional length) { d->length = length; } /// Returns the media type of the file const std::optional &QXmppFileMetadata::mediaType() const { return d->mediaType; } /// Sets the media type of the file void QXmppFileMetadata::setMediaType(std::optional mediaType) { d->mediaType = std::move(mediaType); } /// Returns the filename std::optional QXmppFileMetadata::filename() const { return d->name; } /// Sets the filename void QXmppFileMetadata::setFilename(std::optional name) { d->name = std::move(name); } /// Returns the size of the file in bytes std::optional QXmppFileMetadata::size() const { return d->size; } /// Sets the size of the file in bytes void QXmppFileMetadata::setSize(std::optional size) { d->size = size; } /// Returns the thumbnail references. const QVector &QXmppFileMetadata::thumbnails() const { return d->thumbnails; } /// Sets the thumbnail references. void QXmppFileMetadata::setThumbnails(const QVector &thumbnail) { d->thumbnails = thumbnail; } /// Returns the width of the image or video. std::optional QXmppFileMetadata::width() const { return d->width; } /// Sets the width of the image or video. void QXmppFileMetadata::setWidth(std::optional width) { d->width = width; }