1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // Copyright (C) 2016 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QJSON_P_H |
6 | #define QJSON_P_H |
7 | |
8 | // |
9 | // W A R N I N G |
10 | // ------------- |
11 | // |
12 | // This file is not part of the Qt API. It exists purely as an |
13 | // implementation detail. This header file may change from version to |
14 | // version without notice, or even be removed. |
15 | // |
16 | // We mean it. |
17 | // |
18 | |
19 | #include <qjsonvalue.h> |
20 | #include <qcborvalue.h> |
21 | #include <private/qcborvalue_p.h> |
22 | |
23 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) |
24 | # include <qjsonarray.h> |
25 | # include <qjsonobject.h> |
26 | #endif |
27 | |
28 | QT_BEGIN_NAMESPACE |
29 | |
30 | namespace QJsonPrivate { |
31 | |
32 | template<typename Element, typename ElementsIterator> |
33 | struct ObjectIterator |
34 | { |
35 | using pointer = Element *; |
36 | |
37 | struct value_type; |
38 | struct reference { |
39 | reference(Element &ref) : m_key(&ref) {} |
40 | |
41 | reference() = delete; |
42 | ~reference() = default; |
43 | |
44 | reference(const reference &other) = default; |
45 | reference(reference &&other) = default; |
46 | |
47 | reference &operator=(const value_type &value); |
48 | reference &operator=(const reference &other) |
49 | { |
50 | if (m_key != other.m_key) { |
51 | key() = other.key(); |
52 | value() = other.value(); |
53 | } |
54 | return *this; |
55 | } |
56 | |
57 | reference &operator=(reference &&other) |
58 | { |
59 | key() = other.key(); |
60 | value() = other.value(); |
61 | return *this; |
62 | } |
63 | |
64 | Element &key() { return *m_key; } |
65 | Element &value() { return *(m_key + 1); } |
66 | |
67 | const Element &key() const { return *m_key; } |
68 | const Element &value() const { return *(m_key + 1); } |
69 | |
70 | |
71 | private: |
72 | Element *m_key; |
73 | }; |
74 | |
75 | struct value_type { |
76 | value_type(reference ref) : m_key(ref.key()), m_value(ref.value()) {} |
77 | |
78 | Element key() const { return m_key; } |
79 | Element value() const { return m_value; } |
80 | private: |
81 | Element m_key; |
82 | Element m_value; |
83 | }; |
84 | |
85 | using difference_type = typename QList<Element>::difference_type; |
86 | using iterator_category = std::random_access_iterator_tag; |
87 | |
88 | ObjectIterator() = default; |
89 | ObjectIterator(ElementsIterator it) : it(it) {} |
90 | ElementsIterator elementsIterator() { return it; } |
91 | |
92 | ObjectIterator operator++(int) { ObjectIterator ret(it); it += 2; return ret; } |
93 | ObjectIterator &operator++() { it += 2; return *this; } |
94 | ObjectIterator &operator+=(difference_type n) { it += 2 * n; return *this; } |
95 | |
96 | ObjectIterator operator--(int) { ObjectIterator ret(it); it -= 2; return ret; } |
97 | ObjectIterator &operator--() { it -= 2; return *this; } |
98 | ObjectIterator &operator-=(difference_type n) { it -= 2 * n; return *this; } |
99 | |
100 | reference operator*() const { return *it; } |
101 | reference operator[](qsizetype n) const { return it[n * 2]; } |
102 | |
103 | bool operator<(ObjectIterator other) const { return it < other.it; } |
104 | bool operator>(ObjectIterator other) const { return it > other.it; } |
105 | bool operator<=(ObjectIterator other) const { return it <= other.it; } |
106 | bool operator>=(ObjectIterator other) const { return it >= other.it; } |
107 | |
108 | ElementsIterator it; |
109 | }; |
110 | |
111 | template<typename Element, typename ElementsIterator> |
112 | inline ObjectIterator<Element, ElementsIterator> operator+( |
113 | ObjectIterator<Element, ElementsIterator> a, |
114 | typename ObjectIterator<Element, ElementsIterator>::difference_type n) |
115 | { |
116 | return {a.elementsIterator() + 2 * n}; |
117 | } |
118 | template<typename Element, typename ElementsIterator> |
119 | inline ObjectIterator<Element, ElementsIterator> operator+( |
120 | qsizetype n, ObjectIterator<Element, ElementsIterator> a) |
121 | { |
122 | return {a.elementsIterator() + 2 * n}; |
123 | } |
124 | template<typename Element, typename ElementsIterator> |
125 | inline ObjectIterator<Element, ElementsIterator> operator-( |
126 | ObjectIterator<Element, ElementsIterator> a, |
127 | typename ObjectIterator<Element, ElementsIterator>::difference_type n) |
128 | { |
129 | return {a.elementsIterator() - 2 * n}; |
130 | } |
131 | template<typename Element, typename ElementsIterator> |
132 | inline qsizetype operator-( |
133 | ObjectIterator<Element, ElementsIterator> a, |
134 | ObjectIterator<Element, ElementsIterator> b) |
135 | { |
136 | return (a.elementsIterator() - b.elementsIterator()) / 2; |
137 | } |
138 | template<typename Element, typename ElementsIterator> |
139 | inline bool operator!=( |
140 | ObjectIterator<Element, ElementsIterator> a, |
141 | ObjectIterator<Element, ElementsIterator> b) |
142 | { |
143 | return a.elementsIterator() != b.elementsIterator(); |
144 | } |
145 | template<typename Element, typename ElementsIterator> |
146 | inline bool operator==( |
147 | ObjectIterator<Element, ElementsIterator> a, |
148 | ObjectIterator<Element, ElementsIterator> b) |
149 | { |
150 | return a.elementsIterator() == b.elementsIterator(); |
151 | } |
152 | |
153 | using KeyIterator = ObjectIterator<QtCbor::Element, QList<QtCbor::Element>::iterator>; |
154 | using ConstKeyIterator = ObjectIterator<const QtCbor::Element, QList<QtCbor::Element>::const_iterator>; |
155 | |
156 | template<> |
157 | inline KeyIterator::reference &KeyIterator::reference::operator=(const KeyIterator::value_type &value) |
158 | { |
159 | *m_key = value.key(); |
160 | *(m_key + 1) = value.value(); |
161 | return *this; |
162 | } |
163 | |
164 | inline void swap(KeyIterator::reference a, KeyIterator::reference b) |
165 | { |
166 | KeyIterator::value_type t = a; |
167 | a = b; |
168 | b = t; |
169 | } |
170 | |
171 | class Value |
172 | { |
173 | public: |
174 | static qint64 valueHelper(const QCborValue &v) { return v.n; } |
175 | static QCborContainerPrivate *container(const QCborValue &v) { return v.container; } |
176 | static const QCborContainerPrivate *container(QJsonValueConstRef r) noexcept |
177 | { |
178 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) |
179 | return (r.is_object ? r.o->o : r.a->a).data(); |
180 | #else |
181 | return r.d; |
182 | #endif |
183 | } |
184 | static QCborContainerPrivate *container(QJsonValueRef r) noexcept |
185 | { |
186 | return const_cast<QCborContainerPrivate *>(container(r: QJsonValueConstRef(r))); |
187 | } |
188 | static qsizetype indexHelper(QJsonValueConstRef r) noexcept |
189 | { |
190 | qsizetype index = r.index; |
191 | if (r.is_object) |
192 | index = index * 2 + 1; |
193 | return index; |
194 | } |
195 | static const QtCbor::Element &elementHelper(QJsonValueConstRef r) noexcept |
196 | { |
197 | return container(r)->elements.at(i: indexHelper(r)); |
198 | } |
199 | |
200 | static QJsonValue fromTrustedCbor(const QCborValue &v) |
201 | { |
202 | QJsonValue result; |
203 | result.value = v; |
204 | return result; |
205 | } |
206 | }; |
207 | |
208 | class Variant |
209 | { |
210 | public: |
211 | static QJsonObject toJsonObject(const QVariantMap &map); |
212 | static QJsonArray toJsonArray(const QVariantList &list); |
213 | }; |
214 | |
215 | } // namespace QJsonPrivate |
216 | |
217 | QT_END_NAMESPACE |
218 | |
219 | #endif // QJSON_P_H |
220 | |