9 #include "QXmppGlobal.h" 10 #include "QXmppXmlTags_p.h" 12 #include "Algorithms.h" 17 #include <type_traits> 20 #include <QDomElement> 23 class QXmlStreamWriter;
31 inline auto toString60(QStringView s)
37 concept 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>>;
43 QXMPP_PRIVATE_EXPORT
extern QAtomicInt globalStanzaIdCounter;
46 std::optional<QByteArray> parseBase64(
const QString &);
47 inline QString serializeBase64(
const QByteArray &data) {
return QString::fromUtf8(data.toBase64()); }
50 template<
typename Int =
int>
51 std::optional<Int> parseInt(QStringView str);
52 template<
typename Int>
53 inline QString serializeInt(Int value) {
return QString::number(value); }
56 std::optional<double> parseDouble(QStringView str);
57 std::optional<float> parseFloat(QStringView str);
60 std::optional<bool> parseBoolean(
const QString &str);
61 QString serializeBoolean(
bool);
67 QXMPP_EXPORT QDomElement firstChildElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
68 QXMPP_EXPORT QDomElement nextSiblingElement(
const QDomElement &, QStringView tagName = {}, QStringView xmlNs = {});
71 inline auto firstChildElement(
const QDomElement &el)
74 auto [tag, ns] = T::XmlTag;
75 return firstChildElement(el, tag, ns);
79 inline auto nextSiblingElement(
const QDomElement &el)
82 auto [tag, ns] = T::XmlTag;
83 return nextSiblingElement(el, tag, ns);
86 inline auto hasChild(
const QDomElement &el, QStringView tagName = {}, QStringView xmlns = {})
88 return !firstChildElement(el, tagName, xmlns).isNull();
92 inline auto hasChild(
const QDomElement &el)
95 return !firstChildElement<T>(el).isNull();
98 struct 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 {}; }
122 inline DomChildElements iterChildElements(
const QDomElement &el, QStringView tagName = {}, QStringView namespaceUri = {}) {
return DomChildElements { el, tagName, namespaceUri }; }
125 inline auto iterChildElements(
const QDomElement &el)
126 requires HasXmlTag<T>
128 auto [tag, ns] = T::XmlTag;
129 return iterChildElements(el, tag, ns);
133 concept DomParsableV1 = requires(T t) {
134 { t.parse(QDomElement()) } -> std::same_as<void>;
138 concept DomParsableV2 = requires(T t) {
139 { t.parse(QDomElement()) } -> std::same_as<bool>;
143 concept DomParsableV3 = requires {
144 { T::fromDom(QDomElement()) } -> std::same_as<std::optional<T>>;
148 concept DomParsable = DomParsableV1<T> || DomParsableV2<T> || DomParsableV3<T>;
152 auto 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>) {
172 auto parseOptionalElement(
const QDomElement &domEl) -> std::optional<T>
174 if (domEl.isNull()) {
177 return parseElement<T>(domEl);
182 auto parseOptionalChildElement(
const QDomElement &parentEl, QStringView tagName, QStringView xmlns)
183 requires(!HasXmlTag<T>)
185 return parseOptionalElement<T>(firstChildElement(parentEl, tagName, xmlns));
189 auto parseOptionalChildElement(
const QDomElement &parentEl)
190 requires HasXmlTag<T>
192 auto [tag, ns] = T::XmlTag;
193 return parseOptionalElement<T>(firstChildElement(parentEl, tag, ns));
197 template<
typename Container>
198 auto 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));
213 template<
typename Container>
214 auto 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));
229 template<
typename Container = QList<QString>>
230 auto parseTextElements(
const QDomElement &parent, QStringView tagName, QStringView xmlns)
233 return transform<Container>(iterChildElements(parent, tagName, xmlns), &QDomElement::text);
236 template<
typename Container = QList<QString>>
237 auto 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);
244 QByteArray serializeXmlWriter(std::function<
void(XmlWriter &)>);
245 QByteArray serializeQXmlStream(std::function<
void(QXmlStreamWriter *)>);
248 concept 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>;
257 concept 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>;
263 inline 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) {
277 QXMPP_EXPORT QByteArray generateRandomBytes(
size_t minimumByteCount,
size_t maximumByteCount);
278 QXMPP_EXPORT
void generateRandomBytes(uint8_t *bytes,
size_t byteCount);
279 float calculateProgress(qint64 transferred, qint64 total);
281 QXMPP_EXPORT std::pair<QString, int> parseHostAddress(
const QString &address);
285 #endif // QXMPPUTILS_P_H Definition: QXmppNonza.h:13
Definition: Algorithms.h:14