// SPDX-FileCopyrightText: 2022 Cochise César // // SPDX-License-Identifier: LGPL-2.1-or-later #include "QXmppGeolocItem.h" #include "QXmppConstants_p.h" #include "QXmppUtils.h" #include #include /// \cond class QXmppGeolocItemPrivate : public QSharedData { public: std::optional accuracy; QString country; QString locality; std::optional latitude; std::optional longitude; }; /// \endcond /// /// \class QXmppGeolocItem /// /// This class represents a PubSub item for \xep{0080, User Location}. /// /// \since QXmpp 1.5 /// /// /// Default constructor /// QXmppGeolocItem::QXmppGeolocItem() : d(new QXmppGeolocItemPrivate) { } /// Copy-constructor. QXmppGeolocItem::QXmppGeolocItem(const QXmppGeolocItem &other) = default; /// Move-constructor. QXmppGeolocItem::QXmppGeolocItem(QXmppGeolocItem &&) = default; QXmppGeolocItem::~QXmppGeolocItem() = default; /// Assignment operator. QXmppGeolocItem &QXmppGeolocItem::operator=(const QXmppGeolocItem &other) = default; /// Move-assignment operator. QXmppGeolocItem &QXmppGeolocItem::operator=(QXmppGeolocItem &&) = default; /// /// Returns the horizontal GPS error in meters. /// std::optional QXmppGeolocItem::accuracy() const { return d->accuracy; } /// /// Sets the horizontal GPS error. /// void QXmppGeolocItem::setAccuracy(std::optional accuracy) { d->accuracy = std::move(accuracy); } /// /// Returns the country. /// QString QXmppGeolocItem::country() const { return d->country; } /// /// Sets the country. /// void QXmppGeolocItem::setCountry(QString country) { d->country = std::move(country); } /// /// Returns the latitude in decimal degrees. /// std::optional QXmppGeolocItem::latitude() const { return d->latitude; } /// /// Sets the latitude. /// void QXmppGeolocItem::setLatitude(std::optional lat) { if (lat && (*lat > 90 || *lat < -90)) { d->latitude.reset(); return; } d->latitude = std::move(lat); } /// /// Returns the locality such as a town or a city. /// QString QXmppGeolocItem::locality() const { return d->locality; } /// /// Sets the locality. /// void QXmppGeolocItem::setLocality(QString locality) { d->locality = std::move(locality); } /// /// Returns the longitude in decimal degrees. /// std::optional QXmppGeolocItem::longitude() const { return d->longitude; } /// /// Sets the longitude. /// void QXmppGeolocItem::setLongitude(std::optional lon) { if (lon && (*lon > 180 || *lon < -180)) { d->longitude.reset(); return; } d->longitude = std::move(lon); } /// /// Returns true, if the element is a valid \xep{0080}: User Location PubSub item. /// bool QXmppGeolocItem::isItem(const QDomElement &itemElement) { auto isPayloadValid = [](const QDomElement &payload) -> bool { return payload.tagName() == QStringLiteral("geoloc") && payload.namespaceURI() == ns_geoloc; }; return QXmppPubSubBaseItem::isItem(itemElement, isPayloadValid); } /// \cond std::optional parseOptDouble(const QDomElement &element) { bool ok = false; if (auto val = element.text().toDouble(&ok); ok) { return val; } return {}; } void QXmppGeolocItem::parsePayload(const QDomElement &tune) { for (auto child = tune.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { const auto tagName = child.tagName(); if (tagName == QStringLiteral("accuracy")) { d->accuracy = parseOptDouble(child); } else if (tagName == QStringLiteral("country")) { d->country = child.text(); } else if (tagName == QStringLiteral("lat")) { setLatitude(parseOptDouble(child)); } else if (tagName == QStringLiteral("locality")) { d->locality = child.text(); } else if (tagName == QStringLiteral("lon")) { setLongitude(parseOptDouble(child)); } } } auto writeTextEl(QXmlStreamWriter *writer, const QString &name, const std::optional &val) { if (val.has_value()) { writer->writeTextElement(name, QString::number(*val)); } } auto writeTextEl(QXmlStreamWriter *writer, const QString &name, const QString &val) { helperToXmlAddTextElement(writer, name, val); } void QXmppGeolocItem::serializePayload(QXmlStreamWriter *writer) const { writer->writeStartElement(QStringLiteral("geoloc")); writer->writeDefaultNamespace(ns_geoloc); writeTextEl(writer, QStringLiteral("accuracy"), d->accuracy); writeTextEl(writer, QStringLiteral("country"), d->country); writeTextEl(writer, QStringLiteral("lat"), d->latitude); writeTextEl(writer, QStringLiteral("locality"), d->locality); writeTextEl(writer, QStringLiteral("lon"), d->longitude); writer->writeEndElement(); } /// \endcond