9#include "QXmppGlobal.h"
10#include "QXmppXmlTags_p.h"
12#include "Algorithms.h"
23class QXmlStreamWriter;
26namespace QXmpp::Private {
31inline auto toString60(QStringView s)
33#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
41concept IsStdOptional =
requires {
42 typename std::remove_cvref_t<T>::value_type;
43 requires std::same_as<std::remove_cvref_t<T>, std::optional<typename std::remove_cvref_t<T>::value_type>>;
47QXMPP_PRIVATE_EXPORT
extern QAtomicInt globalStanzaIdCounter;
50std::optional<QByteArray> parseBase64(
const QString &);
51inline QString serializeBase64(
const QByteArray &data) {
return QString::fromUtf8(data.toBase64()); }
54template<
typename Int =
int>
55std::optional<Int> parseInt(QStringView str);
57inline QString serializeInt(Int value) {
return QString::number(value); }
60std::optional<double> parseDouble(QStringView str);
61std::optional<float> parseFloat(QStringView str);
64std::optional<bool> parseBoolean(
const QString &str);
65QString serializeBoolean(
bool);
71QXMPP_EXPORT QDomElement firstChildElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
72QXMPP_EXPORT QDomElement nextSiblingElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
75inline auto firstChildElement(
const QDomElement &el)
78 auto [tag, ns] = T::XmlTag;
79 return firstChildElement(el, tag, ns);
83inline auto nextSiblingElement(
const QDomElement &el)
86 auto [tag, ns] = T::XmlTag;
87 return nextSiblingElement(el, tag, ns);
90inline auto hasChild(
const QDomElement &el, QStringView tagName = {}, QStringView xmlns = {})
92 return !firstChildElement(el, tagName, xmlns).isNull();
96inline auto hasChild(
const QDomElement &el)
99 return !firstChildElement<T>(el).isNull();
102struct DomChildElements {
105 QStringView namespaceUri;
107 struct EndIterator { };
109 Iterator operator++()
111 el = nextSiblingElement(el, tagName, namespaceUri);
114 bool operator!=(EndIterator)
const {
return !el.isNull(); }
115 const QDomElement &operator*()
const {
return el; }
119 QStringView namespaceUri;
122 Iterator begin()
const {
return { firstChildElement(parent, tagName, namespaceUri), tagName, namespaceUri }; }
123 EndIterator end()
const {
return {}; }
126inline DomChildElements iterChildElements(
const QDomElement &el, QStringView tagName = {}, QStringView namespaceUri = {}) {
return DomChildElements { el, tagName, namespaceUri }; }
129inline auto iterChildElements(
const QDomElement &el)
130 requires HasXmlTag<T>
132 auto [tag, ns] = T::XmlTag;
133 return iterChildElements(el, tag, ns);
137concept DomParsableV1 =
requires(T t) {
138 { t.parse(QDomElement()) } -> std::same_as<void>;
142concept DomParsableV2 =
requires(T t) {
143 { t.parse(QDomElement()) } -> std::same_as<bool>;
147concept DomParsableV3 =
requires {
148 { T::fromDom(QDomElement()) } -> std::same_as<std::optional<T>>;
152concept DomParsable = DomParsableV1<T> || DomParsableV2<T> || DomParsableV3<T>;
156auto parseElement(
const QDomElement &el) -> std::optional<T>
157 requires DomParsable<T>
159 if constexpr (DomParsableV3<T>) {
160 return T::fromDom(el);
161 }
else if constexpr (DomParsableV2<T>) {
163 if (!element.parse(el)) {
167 }
else if constexpr (DomParsableV1<T>) {
176auto parseOptionalElement(
const QDomElement &domEl) -> std::optional<T>
178 if (domEl.isNull()) {
181 return parseElement<T>(domEl);
186auto parseOptionalChildElement(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
187 requires(!HasXmlTag<T>)
189 return parseOptionalElement<T>(firstChildElement(parentEl, tagName, xmlns));
193auto parseOptionalChildElement(
const QDomElement &parentEl)
194 requires HasXmlTag<T>
196 auto [tag, ns] = T::XmlTag;
197 return parseOptionalElement<T>(firstChildElement(parentEl, tag, ns));
201template<
typename Container>
202auto parseChildElements(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
204 requires(!HasXmlTag<typename Container::value_type>)
206 using T =
typename Container::value_type;
209 for (
const auto &childEl : iterChildElements(parentEl, tagName, xmlns)) {
210 if (
auto parsedEl = parseElement<T>(childEl)) {
211 elements.push_back(std::move(*parsedEl));
217template<
typename Container>
218auto parseChildElements(
const QDomElement &parentEl) -> Container
219 requires HasXmlTag<typename Container::value_type>
221 using T =
typename Container::value_type;
222 auto [tag, ns] = T::XmlTag;
225 for (
const auto &childEl : iterChildElements(parentEl, tag, ns)) {
226 if (
auto parsedEl = parseElement<T>(childEl)) {
227 elements.push_back(std::move(*parsedEl));
233template<
typename Container = QList<QString>>
234auto parseTextElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns)
237 return transform<Container>(iterChildElements(parent, tagName, xmlns), &QDomElement::text);
240template<
typename Container = QList<QString>>
241auto parseSingleAttributeElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns,
const QString &attribute)
243 return transform<Container>(iterChildElements(parent, tagName, xmlns), [=](
const QDomElement &el) {
244 return el.attribute(attribute);
248QByteArray serializeXmlWriter(std::function<
void(XmlWriter &)>);
249QByteArray serializeQXmlStream(std::function<
void(QXmlStreamWriter *)>);
252concept XmlWriterSerializeable =
254 decltype(
static_cast<void (std::remove_cvref_t<T>::*)(XmlWriter &)
>(&std::remove_cvref_t<T>::toXml)),
255 void (std::remove_cvref_t<T>::*)(XmlWriter &)> ||
257 decltype(static_cast<void (std::remove_cvref_t<T>::*)(XmlWriter &) const>(&std::remove_cvref_t<T>::toXml)),
258 void (std::remove_cvref_t<T>::*)(XmlWriter &) const>;
261concept QXmlStreamSerializeable =
263 decltype(
static_cast<void (std::remove_cvref_t<T>::*)(QXmlStreamWriter *) const
>(&std::remove_cvref_t<T>::toXml)),
264 void (std::remove_cvref_t<T>::*)(QXmlStreamWriter *) const>;
267inline QByteArray serializeXml(
const T &packet)
268 requires XmlWriterSerializeable<T> || QXmlStreamSerializeable<T>
270 if constexpr (XmlWriterSerializeable<T>) {
271 return serializeXmlWriter([&](XmlWriter &w) {
274 }
else if constexpr (QXmlStreamSerializeable<T>) {
275 return serializeQXmlStream([&](QXmlStreamWriter *w) {
281QXMPP_EXPORT QByteArray generateRandomBytes(
size_t minimumByteCount,
size_t maximumByteCount);
282QXMPP_EXPORT
void generateRandomBytes(uint8_t *bytes,
size_t byteCount);
283float calculateProgress(qint64 transferred, qint64 total);
285QXMPP_EXPORT std::pair<QString, int> parseHostAddress(
const QString &address);
Definition QXmppNonza.h:14