Skip to content

Commit

Permalink
Improve vcard4 api
Browse files Browse the repository at this point in the history
  • Loading branch information
Ri0n committed Jun 9, 2024
1 parent df3de9b commit 7fc1244
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 61 deletions.
4 changes: 1 addition & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ include(policyRules)

set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)

# Detect MXE cross-compilation
set(IRIS_DEFAULT_BUNDLED_USRSCTP OFF)
Expand Down Expand Up @@ -69,8 +69,6 @@ option(IRIS_ENABLE_DEBUG "Enable debugging code paths" OFF)

set(IRIS_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}/xmpp/iris)

set(CMAKE_CXX_STANDARD 17)

if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo"))
include(debug-definitions)
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/irisnet/corelib/netinterface_qtnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class InterfaceMonitor : public QObject {
notifier = new QSocketNotifier(netlinkFd, QSocketNotifier::Read, this);

connect(notifier, &QSocketNotifier::activated, this,
[=](QSocketDescriptor, QSocketNotifier::Type) { emit changed(); });
[this](QSocketDescriptor, QSocketNotifier::Type) { emit changed(); });
}

~InterfaceMonitor()
Expand Down
66 changes: 31 additions & 35 deletions src/xmpp/xmpp-im/xmpp_vcard4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace {
}
auto doc = parent.ownerDocument();
auto bday = parent.appendChild(doc.createElement(QLatin1String(tagName))).toElement();
historical.first.addTo(bday);
historical.parameters.addTo(bday);
using Tv = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<Tv, QString>) {
VCardHelper::addTextElement(doc, bday, QLatin1String("text"), QStringList { v });
Expand All @@ -95,7 +95,7 @@ namespace {
QStringList { v.toString(Qt::ISODate) });
}
},
historical.second);
historical.data);
}

template <typename ListType>
Expand All @@ -113,17 +113,17 @@ namespace {
}

template <typename T>
static void serializeList(QDomElement &parent, const QList<std::pair<Parameters, T>> &list,
const QString &tagName, const QString &innerTagName = QLatin1String("text"))
static void serializeList(QDomElement &parent, const TaggedList<T> &list, const QString &tagName,
const QString &innerTagName = QLatin1String("text"))
{
auto document = parent.ownerDocument();
for (const auto &entry : list) {
QDomElement element = document.createElement(tagName);
entry.first.addTo(element);
entry.parameters.addTo(element);
if constexpr (std::is_same_v<T, QString>) {
addTextElement(document, element, QLatin1String("text"), QStringList { entry.second });
addTextElement(document, element, QLatin1String("text"), QStringList { entry.data });
} else if constexpr (std::is_same_v<T, QUrl> || std::is_same_v<T, UriValue>) {
addTextElement(document, element, QLatin1String("uri"), QStringList { entry.second.toString() });
addTextElement(document, element, QLatin1String("uri"), QStringList { entry.data.toString() });
} else if constexpr (std::is_same_v<T, UriOrText>) {
std::visit(
[&](auto v) {
Expand All @@ -134,9 +134,9 @@ namespace {
addTextElement(document, element, QLatin1String("text"), QStringList { v });
}
},
entry.second);
entry.data);
} else if constexpr (std::is_same_v<T, QStringList>) {
for (auto const &s : entry.second) {
for (auto const &s : entry.data) {
element.appendChild(document.createElement(QLatin1String("text")))
.appendChild(document.createTextNode(s));
}
Expand All @@ -158,7 +158,7 @@ namespace {
addTextElement(document, element, QLatin1String("text"), QStringList { v });
}
},
entry.second);
entry.data);
} else {
throw std::logic_error("should never happen. some type is not supported");
}
Expand Down Expand Up @@ -202,8 +202,7 @@ namespace {
}

template <typename ItemT>
static void fillContainer(QDomElement parent, const char *tagName,
QList<std::pair<Parameters, ItemT>> &container)
static void fillContainer(QDomElement parent, const char *tagName, TaggedList<ItemT> &container)
{
auto tn = QString::fromLatin1(tagName);
for (auto e = parent.firstChildElement(tn); !e.isNull(); e = e.nextSiblingElement(tn)) {
Expand Down Expand Up @@ -253,28 +252,28 @@ namespace {
if (source.isNull()) {
return;
}
to.first = Parameters(source.firstChildElement(QLatin1String("parameters")));
auto v = VCardHelper::extractText(source, "date");
to.parameters = Parameters(source.firstChildElement(QLatin1String("parameters")));
auto v = VCardHelper::extractText(source, "date");
if (v.isNull()) {
v = VCardHelper::extractText(source, "date-time");
if (v.isNull()) {
v = VCardHelper::extractText(source, "time");
if (v.isNull()) {
to.second = VCardHelper::extractText(source, "text");
to.data = VCardHelper::extractText(source, "text");
} else {
to.second = QTime::fromString(v, Qt::ISODate);
to.data = QTime::fromString(v, Qt::ISODate);
}
} else {
to.second = QDateTime::fromString(v, Qt::ISODate);
to.data = QDateTime::fromString(v, Qt::ISODate);
}
} else {
to.second = QDate::fromString(v, Qt::ISODate);
to.data = QDate::fromString(v, Qt::ISODate);
}
}

static bool isNull(const PHistorical &h)
{
return std::visit([](auto const &v) { return v.isNull(); }, h.second);
return std::visit([](auto const &v) { return v.isNull(); }, h.data);
}
};

Expand Down Expand Up @@ -480,7 +479,7 @@ class VCard::VCardData : public QSharedData {
QString genderComment;

// Delivery Addressing Properties
QList<std::pair<Parameters, Address>> addresses; // any number of addresses
PAddresses addresses; // any number of addresses

// Communications Properties
PUrisOrTexts tels; // any number of telephones
Expand Down Expand Up @@ -605,7 +604,7 @@ class VCard::VCardData : public QSharedData {

bool isEmpty() const
{
return fullName.isEmpty() && names.second.isEmpty() && nickname.isEmpty() && emails.isEmpty() && tels.isEmpty()
return fullName.isEmpty() && names.data.isEmpty() && nickname.isEmpty() && emails.isEmpty() && tels.isEmpty()
&& org.isEmpty() && title.isEmpty() && role.isEmpty() && note.isEmpty() && urls.isEmpty()
&& VCardHelper::isNull(bday) && VCardHelper::isNull(anniversary) && gender == VCard4::Gender::Undefined
&& uid.isEmpty() && kind.isEmpty() && categories.isEmpty() && busyTimeUrl.isEmpty()
Expand Down Expand Up @@ -640,9 +639,9 @@ QDomElement VCard::toXmlElement(QDomDocument &document) const
QDomElement vCardElement = document.createElement(QLatin1String("vcard"));

VCardHelper::serializeList(vCardElement, d->fullName, QLatin1String("fn"));
if (!d->names.second.isEmpty()) {
auto e = vCardElement.appendChild(d->names.second.toXmlElement(document)).toElement();
d->names.first.addTo(e);
if (!d->names.data.isEmpty()) {
auto e = vCardElement.appendChild(d->names.data.toXmlElement(document)).toElement();
d->names.parameters.addTo(e);
}
VCardHelper::serializeList(vCardElement, d->nickname, QLatin1String("nickname"), QLatin1String("text"));
VCardHelper::serializeList(vCardElement, d->emails, QLatin1String("email"), QLatin1String("text"));
Expand Down Expand Up @@ -694,8 +693,8 @@ QDomElement VCard::toXmlElement(QDomDocument &document) const

for (const auto &address : d->addresses) {
QDomElement adrElement = document.createElement(QLatin1String("adr"));
address.first.addTo(adrElement);
adrElement.appendChild(address.second.toXmlElement(document));
address.parameters.addTo(adrElement);
adrElement.appendChild(address.data.toXmlElement(document));
vCardElement.appendChild(adrElement);
}

Expand Down Expand Up @@ -791,9 +790,9 @@ void VCard::setEmails(const PStrings &emails)
d->emails = emails;
}

PUrisOrTexts VCard::tels() const { return d ? d->tels : PUrisOrTexts(); }
PUrisOrTexts VCard::phones() const { return d ? d->tels : PUrisOrTexts(); }

void VCard::setTels(const PUrisOrTexts &tels)
void VCard::setPhones(const PUrisOrTexts &tels)
{
INIT_D();
d->tels = tels;
Expand Down Expand Up @@ -951,9 +950,9 @@ void VCard::setKey(const PUrisOrTexts &key)
d->key = key;
}

PStrings VCard::lang() const { return d ? d->lang : PStrings(); }
PStrings VCard::languages() const { return d ? d->lang : PStrings(); }

void VCard::setLang(const PStrings &lang)
void VCard::setLanguages(const PStrings &lang)
{
INIT_D();
d->lang = lang;
Expand Down Expand Up @@ -1031,12 +1030,9 @@ void VCard::setTimeZone(const PTimeZones &timeZone)
d->timeZone = timeZone;
}

QList<std::pair<Parameters, Address>> VCard::addresses() const
{
return d ? d->addresses : QList<std::pair<Parameters, Address>>();
}
PAddresses VCard::addresses() const { return d ? d->addresses : PAddresses(); }

void VCard::setAddresses(const QList<std::pair<Parameters, Address>> &addresses)
void VCard::setAddresses(const PAddresses &addresses)
{
INIT_D();
d->addresses = addresses;
Expand Down
66 changes: 44 additions & 22 deletions src/xmpp/xmpp-im/xmpp_vcard4.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <QStringList>
#include <QUrl>

#include <algorithm>
#include <variant>

/**
Expand Down Expand Up @@ -100,28 +101,49 @@ class UriValue {
QString mediaType;
};

template <typename T> struct Item {
Parameters parameters;
T data;

operator QString() const { return data; }
};

template <typename T> class TaggedList : public QList<T> {
public:
using item_type = T;

T preferred() const
{
if (this->empty()) {
return {};
}
return *std::ranges::max_element(
*this, [](auto const &a, auto const &b) { return a.parameters.pref > b.parameters.pref; });
}
};

using UriOrText = std::variant<QUrl, QString>;
using TimeZone = std::variant<QUrl, QString, int>;
using Historical = std::variant<QDateTime, QDate, QTime, QString>;

using PStringList = std::pair<Parameters, QStringList>;
using PString = std::pair<Parameters, QString>;
using PUri = std::pair<Parameters, QUrl>;
using PDate = std::pair<Parameters, QDate>;
using PAdvUri = std::pair<Parameters, UriValue>;
using PAddress = std::pair<Parameters, Address>;
using PNames = std::pair<Parameters, Names>;
using PUriOrText = std::pair<Parameters, UriOrText>;
using PTimeZone = std::pair<Parameters, TimeZone>;
using PHistorical = std::pair<Parameters, Historical>;

using PStringLists = QList<PStringList>;
using PStrings = QList<PString>;
using PUris = QList<PUri>;
using PAdvUris = QList<PAdvUri>;
using PAddresses = QList<PAddress>;
using PUrisOrTexts = QList<PUriOrText>;
using PTimeZones = QList<PTimeZone>;
using PStringList = Item<QStringList>;
using PString = Item<QString>;
using PUri = Item<QUrl>;
using PDate = Item<QDate>;
using PAdvUri = Item<UriValue>;
using PAddress = Item<Address>;
using PNames = Item<Names>;
using PUriOrText = Item<UriOrText>;
using PTimeZone = Item<TimeZone>;
using PHistorical = Item<Historical>;

using PStringLists = TaggedList<PStringList>;
using PStrings = TaggedList<PString>;
using PUris = TaggedList<PUri>;
using PAdvUris = TaggedList<PAdvUri>;
using PAddresses = TaggedList<PAddress>;
using PUrisOrTexts = TaggedList<PUriOrText>;
using PTimeZones = TaggedList<PTimeZone>;

class VCard {
public:
Expand Down Expand Up @@ -150,8 +172,8 @@ class VCard {
PStrings emails() const;
void setEmails(const PStrings &emails);

PUrisOrTexts tels() const;
void setTels(const PUrisOrTexts &tels);
PUrisOrTexts phones() const;
void setPhones(const PUrisOrTexts &tels);

PStringLists org() const;
void setOrg(const PStringLists &org);
Expand Down Expand Up @@ -210,8 +232,8 @@ class VCard {
PUrisOrTexts key() const;
void setKey(const PUrisOrTexts &key);

PStrings lang() const;
void setLang(const PStrings &lang);
PStrings languages() const;
void setLanguages(const PStrings &lang);

PAdvUris logo() const;
void setLogo(const PAdvUris &logo);
Expand Down

0 comments on commit 7fc1244

Please sign in to comment.