9#include "QXmppGlobal.h"
10#include "QXmppXmlTags_p.h"
12#include "Algorithms.h"
22class QXmlStreamWriter;
25namespace QXmpp::Private {
30inline auto toString60(QStringView s)
32#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
40concept IsStdOptional =
requires {
41 typename std::remove_cvref_t<T>::value_type;
42 requires std::same_as<std::remove_cvref_t<T>, std::optional<typename std::remove_cvref_t<T>::value_type>>;
46QXMPP_PRIVATE_EXPORT
extern QAtomicInt globalStanzaIdCounter;
49std::optional<QByteArray> parseBase64(
const QString &);
50inline QString serializeBase64(
const QByteArray &data) {
return QString::fromUtf8(data.toBase64()); }
53template<
typename Int =
int>
54std::optional<Int> parseInt(QStringView str);
56inline QString serializeInt(Int value) {
return QString::number(value); }
59std::optional<double> parseDouble(QStringView str);
60std::optional<float> parseFloat(QStringView str);
63std::optional<bool> parseBoolean(
const QString &str);
64QString serializeBoolean(
bool);
70QXMPP_EXPORT QDomElement firstChildElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
71QXMPP_EXPORT QDomElement nextSiblingElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
74inline auto firstChildElement(
const QDomElement &el)
77 auto [tag, ns] = T::XmlTag;
78 return firstChildElement(el, tag, ns);
82inline auto nextSiblingElement(
const QDomElement &el)
85 auto [tag, ns] = T::XmlTag;
86 return nextSiblingElement(el, tag, ns);
89inline auto hasChild(
const QDomElement &el, QStringView tagName = {}, QStringView xmlns = {})
91 return !firstChildElement(el, tagName, xmlns).isNull();
95inline auto hasChild(
const QDomElement &el)
98 return !firstChildElement<T>(el).isNull();
101struct DomChildElements {
104 QStringView namespaceUri;
106 struct EndIterator { };
108 Iterator operator++()
110 el = nextSiblingElement(el, tagName, namespaceUri);
113 bool operator!=(EndIterator)
const {
return !el.isNull(); }
114 const QDomElement &operator*()
const {
return el; }
118 QStringView namespaceUri;
121 Iterator begin()
const {
return { firstChildElement(parent, tagName, namespaceUri), tagName, namespaceUri }; }
122 EndIterator end()
const {
return {}; }
125inline DomChildElements iterChildElements(
const QDomElement &el, QStringView tagName = {}, QStringView namespaceUri = {}) {
return DomChildElements { el, tagName, namespaceUri }; }
128inline auto iterChildElements(
const QDomElement &el)
129 requires HasXmlTag<T>
131 auto [tag, ns] = T::XmlTag;
132 return iterChildElements(el, tag, ns);
136concept DomParsableV1 =
requires(T t) {
137 { t.parse(QDomElement()) } -> std::same_as<void>;
141concept DomParsableV2 =
requires(T t) {
142 { t.parse(QDomElement()) } -> std::same_as<bool>;
146concept DomParsableV3 =
requires {
147 { T::fromDom(QDomElement()) } -> std::same_as<std::optional<T>>;
151concept DomParsable = DomParsableV1<T> || DomParsableV2<T> || DomParsableV3<T>;
155auto parseElement(
const QDomElement &el) -> std::optional<T>
156 requires DomParsable<T>
158 if constexpr (DomParsableV3<T>) {
159 return T::fromDom(el);
160 }
else if constexpr (DomParsableV2<T>) {
162 if (!element.parse(el)) {
166 }
else if constexpr (DomParsableV1<T>) {
175auto parseOptionalElement(
const QDomElement &domEl) -> std::optional<T>
177 if (domEl.isNull()) {
180 return parseElement<T>(domEl);
185auto parseOptionalChildElement(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
186 requires(!HasXmlTag<T>)
188 return parseOptionalElement<T>(firstChildElement(parentEl, tagName, xmlns));
192auto parseOptionalChildElement(
const QDomElement &parentEl)
193 requires HasXmlTag<T>
195 auto [tag, ns] = T::XmlTag;
196 return parseOptionalElement<T>(firstChildElement(parentEl, tag, ns));
200template<
typename Container>
201auto parseChildElements(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
203 requires(!HasXmlTag<typename Container::value_type>)
205 using T =
typename Container::value_type;
208 for (
const auto &childEl : iterChildElements(parentEl, tagName, xmlns)) {
209 if (
auto parsedEl = parseElement<T>(childEl)) {
210 elements.push_back(std::move(*parsedEl));
216template<
typename Container>
217auto parseChildElements(
const QDomElement &parentEl) -> Container
218 requires HasXmlTag<typename Container::value_type>
220 using T =
typename Container::value_type;
221 auto [tag, ns] = T::XmlTag;
224 for (
const auto &childEl : iterChildElements(parentEl, tag, ns)) {
225 if (
auto parsedEl = parseElement<T>(childEl)) {
226 elements.push_back(std::move(*parsedEl));
232template<
typename Container = QList<QString>>
233auto parseTextElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns)
236 return transform<Container>(iterChildElements(parent, tagName, xmlns), &QDomElement::text);
239template<
typename Container = QList<QString>>
240auto parseSingleAttributeElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns,
const QString &attribute)
242 return transform<Container>(iterChildElements(parent, tagName, xmlns), [=](
const QDomElement &el) {
243 return el.attribute(attribute);
247QByteArray serializeXml(std::function<
void(XmlWriter &)>);
248QByteArray serializeXml(std::function<
void(QXmlStreamWriter *)>);
251concept XmlWriterSerializeable =
requires(T packet, XmlWriter &writer) {
252 { packet.toXml(writer) } -> std::same_as<void>;
255concept QXmlStreamSerializeable =
requires(T packet, QXmlStreamWriter *writer) {
256 { packet.toXml(writer) } -> std::same_as<void>;
260inline QByteArray serializeXml(
const T &packet)
261 requires XmlWriterSerializeable<T> || QXmlStreamSerializeable<T>
263 if constexpr (XmlWriterSerializeable<T>) {
264 return serializeXml([&](XmlWriter &w) {
267 }
else if constexpr (QXmlStreamSerializeable<T>) {
268 return serializeXml([&](QXmlStreamWriter *w) {
274QXMPP_EXPORT QByteArray generateRandomBytes(
size_t minimumByteCount,
size_t maximumByteCount);
275QXMPP_EXPORT
void generateRandomBytes(uint8_t *bytes,
size_t byteCount);
276float calculateProgress(qint64 transferred, qint64 total);
278QXMPP_EXPORT std::pair<QString, int> parseHostAddress(
const QString &address);
Definition QXmppNonza.h:14