9#include "QXmppGlobal.h"
10#include "QXmppXmlTags_p.h"
12#include "Algorithms.h"
23class QXmlStreamWriter;
26namespace QXmpp::Private {
31inline auto toString60(QStringView s)
37concept IsStdOptional =
requires {
38 typename std::remove_cvref_t<T>::value_type;
39 requires std::same_as<std::remove_cvref_t<T>, std::optional<typename std::remove_cvref_t<T>::value_type>>;
43QXMPP_PRIVATE_EXPORT
extern QAtomicInt globalStanzaIdCounter;
46std::optional<QByteArray> parseBase64(
const QString &);
47inline QString serializeBase64(
const QByteArray &data) {
return QString::fromUtf8(data.toBase64()); }
50template<
typename Int =
int>
51std::optional<Int> parseInt(QStringView str);
53inline QString serializeInt(Int value) {
return QString::number(value); }
56std::optional<double> parseDouble(QStringView str);
57std::optional<float> parseFloat(QStringView str);
60std::optional<bool> parseBoolean(
const QString &str);
61QString serializeBoolean(
bool);
67QXMPP_EXPORT QDomElement firstChildElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
68QXMPP_EXPORT QDomElement nextSiblingElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
71inline auto firstChildElement(
const QDomElement &el)
74 auto [tag, ns] = T::XmlTag;
75 return firstChildElement(el, tag, ns);
79inline auto nextSiblingElement(
const QDomElement &el)
82 auto [tag, ns] = T::XmlTag;
83 return nextSiblingElement(el, tag, ns);
86inline auto hasChild(
const QDomElement &el, QStringView tagName = {}, QStringView xmlns = {})
88 return !firstChildElement(el, tagName, xmlns).isNull();
92inline auto hasChild(
const QDomElement &el)
95 return !firstChildElement<T>(el).isNull();
98struct DomChildElements {
101 QStringView namespaceUri;
103 struct EndIterator { };
105 Iterator operator++()
107 el = nextSiblingElement(el, tagName, namespaceUri);
110 bool operator!=(EndIterator)
const {
return !el.isNull(); }
111 const QDomElement &operator*()
const {
return el; }
115 QStringView namespaceUri;
118 Iterator begin()
const {
return { firstChildElement(parent, tagName, namespaceUri), tagName, namespaceUri }; }
119 EndIterator end()
const {
return {}; }
122inline DomChildElements iterChildElements(
const QDomElement &el, QStringView tagName = {}, QStringView namespaceUri = {}) {
return DomChildElements { el, tagName, namespaceUri }; }
125inline auto iterChildElements(
const QDomElement &el)
126 requires HasXmlTag<T>
128 auto [tag, ns] = T::XmlTag;
129 return iterChildElements(el, tag, ns);
133concept DomParsableV1 =
requires(T t) {
134 { t.parse(QDomElement()) } -> std::same_as<void>;
138concept DomParsableV2 =
requires(T t) {
139 { t.parse(QDomElement()) } -> std::same_as<bool>;
143concept DomParsableV3 =
requires {
144 { T::fromDom(QDomElement()) } -> std::same_as<std::optional<T>>;
148concept DomParsable = DomParsableV1<T> || DomParsableV2<T> || DomParsableV3<T>;
152auto parseElement(
const QDomElement &el) -> std::optional<T>
153 requires DomParsable<T>
155 if constexpr (DomParsableV3<T>) {
156 return T::fromDom(el);
157 }
else if constexpr (DomParsableV2<T>) {
159 if (!element.parse(el)) {
163 }
else if constexpr (DomParsableV1<T>) {
172auto parseOptionalElement(
const QDomElement &domEl) -> std::optional<T>
174 if (domEl.isNull()) {
177 return parseElement<T>(domEl);
182auto parseOptionalChildElement(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
183 requires(!HasXmlTag<T>)
185 return parseOptionalElement<T>(firstChildElement(parentEl, tagName, xmlns));
189auto parseOptionalChildElement(
const QDomElement &parentEl)
190 requires HasXmlTag<T>
192 auto [tag, ns] = T::XmlTag;
193 return parseOptionalElement<T>(firstChildElement(parentEl, tag, ns));
197template<
typename Container>
198auto parseChildElements(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
200 requires(!HasXmlTag<typename Container::value_type>)
202 using T =
typename Container::value_type;
205 for (
const auto &childEl : iterChildElements(parentEl, tagName, xmlns)) {
206 if (
auto parsedEl = parseElement<T>(childEl)) {
207 elements.push_back(std::move(*parsedEl));
213template<
typename Container>
214auto parseChildElements(
const QDomElement &parentEl) -> Container
215 requires HasXmlTag<typename Container::value_type>
217 using T =
typename Container::value_type;
218 auto [tag, ns] = T::XmlTag;
221 for (
const auto &childEl : iterChildElements(parentEl, tag, ns)) {
222 if (
auto parsedEl = parseElement<T>(childEl)) {
223 elements.push_back(std::move(*parsedEl));
229template<
typename Container = QList<QString>>
230auto parseTextElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns)
233 return transform<Container>(iterChildElements(parent, tagName, xmlns), &QDomElement::text);
236template<
typename Container = QList<QString>>
237auto parseSingleAttributeElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns,
const QString &attribute)
239 return transform<Container>(iterChildElements(parent, tagName, xmlns), [=](
const QDomElement &el) {
240 return el.attribute(attribute);
244QByteArray serializeXmlWriter(std::function<
void(XmlWriter &)>);
245QByteArray serializeQXmlStream(std::function<
void(QXmlStreamWriter *)>);
248concept XmlWriterSerializeable =
250 decltype(
static_cast<void (std::remove_cvref_t<T>::*)(XmlWriter &)
>(&std::remove_cvref_t<T>::toXml)),
251 void (std::remove_cvref_t<T>::*)(XmlWriter &)> ||
253 decltype(static_cast<void (std::remove_cvref_t<T>::*)(XmlWriter &) const>(&std::remove_cvref_t<T>::toXml)),
254 void (std::remove_cvref_t<T>::*)(XmlWriter &) const>;
257concept QXmlStreamSerializeable =
259 decltype(
static_cast<void (std::remove_cvref_t<T>::*)(QXmlStreamWriter *) const
>(&std::remove_cvref_t<T>::toXml)),
260 void (std::remove_cvref_t<T>::*)(QXmlStreamWriter *) const>;
263inline QByteArray serializeXml(
const T &packet)
264 requires XmlWriterSerializeable<T> || QXmlStreamSerializeable<T>
266 if constexpr (XmlWriterSerializeable<T>) {
267 return serializeXmlWriter([&](XmlWriter &w) {
270 }
else if constexpr (QXmlStreamSerializeable<T>) {
271 return serializeQXmlStream([&](QXmlStreamWriter *w) {
277QXMPP_EXPORT QByteArray generateRandomBytes(
size_t minimumByteCount,
size_t maximumByteCount);
278QXMPP_EXPORT
void generateRandomBytes(uint8_t *bytes,
size_t byteCount);
279float calculateProgress(qint64 transferred, qint64 total);
281QXMPP_EXPORT std::pair<QString, int> parseHostAddress(
const QString &address);
Definition QXmppNonza.h:14