diff options
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r-- | src/corelib/serialization/qcborarray.cpp | 6 | ||||
-rw-r--r-- | src/corelib/serialization/qcborstream.cpp | 10 | ||||
-rw-r--r-- | src/corelib/serialization/qjson.cpp | 6 | ||||
-rw-r--r-- | src/corelib/serialization/qjson_p.h | 97 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonarray.cpp | 2 | ||||
-rw-r--r-- | src/corelib/serialization/qjsoncbor.cpp | 2 | ||||
-rw-r--r-- | src/corelib/serialization/qjsondocument.cpp | 11 | ||||
-rw-r--r-- | src/corelib/serialization/qjsondocument.h | 3 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonobject.cpp | 307 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonobject.h | 41 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonvalue.cpp | 11 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonvalue.h | 3 | ||||
-rw-r--r-- | src/corelib/serialization/qtextstream.cpp | 2 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream.cpp | 6 |
14 files changed, 407 insertions, 100 deletions
diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index 28ae40f3df..ca0156e07d 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -273,7 +273,7 @@ QCborValue QCborArray::at(qsizetype i) const not be empty. QCborValueRef has the exact same API as \l QCborValue, with one important - difference: if you assign new values to it, this map will be updated with + difference: if you assign new values to it, this array will be updated with that new value. \sa operator[](), at(), last(), insert(), prepend(), append(), @@ -287,7 +287,7 @@ QCborValue QCborArray::at(qsizetype i) const not be empty. QCborValueRef has the exact same API as \l QCborValue, with one important - difference: if you assign new values to it, this map will be updated with + difference: if you assign new values to it, this array will be updated with that new value. \sa operator[](), at(), first(), insert(), prepend(), append(), @@ -302,7 +302,7 @@ QCborValue QCborArray::at(qsizetype i) const with undefined entries, until it has an entry at the specified index. QCborValueRef has the exact same API as \l QCborValue, with one important - difference: if you assign new values to it, this map will be updated with + difference: if you assign new values to it, this array will be updated with that new value. \sa at(), first(), last(), insert(), prepend(), append(), diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index 078c14a32d..c598eee213 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -1972,7 +1972,15 @@ inline void QCborStreamReader::preparse() if (lastError() == QCborError::NoError) { type_ = cbor_value_get_type(&d->currentElement); - if (type_ != CborInvalidType) { + if (type_ == CborInvalidType) { + // We may have reached the end. + if (d->device && d->containerStack.isEmpty()) { + d->buffer.clear(); + if (d->bufferStart) + d->device->skip(d->bufferStart); + d->bufferStart = 0; + } + } else { d->lastError = {}; // Undo the type mapping that TinyCBOR does (we have an explicit type // for negative integer and we don't have separate types for Boolean, diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index d74ffb2a20..76f1eae1ce 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -175,7 +175,7 @@ void Base::removeItems(int pos, int numItems) length -= numItems; } -int Object::indexOf(const QString &key, bool *exists) const +int Object::indexOf(QStringView key, bool *exists) const { int min = 0; int n = length; @@ -257,7 +257,7 @@ bool Array::isValid(int maxSize) const } -bool Entry::operator ==(const QString &key) const +bool Entry::operator ==(QStringView key) const { if (value.latinKey) return (shallowLatin1Key() == key); @@ -270,7 +270,7 @@ bool Entry::operator==(QLatin1String key) const if (value.latinKey) return shallowLatin1Key() == key; else - return shallowKey() == key; + return shallowKey() == QString(key); // ### conversion to QString } bool Entry::operator ==(const Entry &other) const diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 9de53d5b74..7978bed7da 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -66,11 +66,13 @@ #include <limits.h> #include <limits> +#include <type_traits> QT_BEGIN_NAMESPACE // in qstring.cpp void qt_to_latin1_unchecked(uchar *dst, const ushort *uc, qsizetype len); +void qt_from_latin1(ushort *dst, const char *str, size_t size) noexcept; /* This defines a binary data structure for Json data. The data structure is optimised for fast reading @@ -153,16 +155,24 @@ typedef qle_uint offset; // round the size up to the next 4 byte boundary inline int alignedSize(int size) { return (size + 3) & ~3; } -static inline bool useCompressed(const QString &s) +const int MaxLatin1Length = 0x7fff; + +static inline bool useCompressed(QStringView s) { - if (s.length() >= 0x8000) + if (s.length() > MaxLatin1Length) return false; return QtPrivate::isLatin1(s); } -static inline int qStringSize(const QString &string, bool compress) +static inline bool useCompressed(QLatin1String s) +{ + return s.size() <= MaxLatin1Length; +} + +template <typename T> +static inline int qStringSize(T string, bool compress) { - int l = 2 + string.length(); + int l = 2 + string.size(); if (!compress) l *= 2; return alignedSize(l); @@ -214,37 +224,49 @@ public: return maxSize >= 0 && uint(d->length) <= maxSize / sizeof(ushort); } - inline String &operator=(const QString &str) + inline String &operator=(QStringView str) { d->length = str.length(); + qToLittleEndian<quint16>(str.utf16(), str.length(), d->utf16); + fillTrailingZeros(); + return *this; + } + + inline String &operator=(QLatin1String str) + { + d->length = str.size(); #if Q_BYTE_ORDER == Q_BIG_ENDIAN - const ushort *uc = (const ushort *)str.unicode(); - for (int i = 0; i < str.length(); ++i) - d->utf16[i] = uc[i]; + for (int i = 0; i < str.size(); ++i) + d->utf16[i] = str[i].unicode(); #else - memcpy(d->utf16, str.unicode(), str.length()*sizeof(ushort)); + qt_from_latin1((ushort *)d->utf16, str.data(), str.size()); #endif - if (str.length() & 1) - d->utf16[str.length()] = 0; + fillTrailingZeros(); return *this; } - inline bool operator ==(const QString &str) const { + void fillTrailingZeros() + { + if (d->length & 1) + d->utf16[d->length] = 0; + } + + inline bool operator ==(QStringView str) const { int slen = str.length(); int l = d->length; if (slen != l) return false; - const ushort *s = (const ushort *)str.constData(); + const ushort *s = (const ushort *)str.utf16(); const qle_ushort *a = d->utf16; const ushort *b = s; while (l-- && *a == *b) a++,b++; return (l == -1); } - inline bool operator !=(const QString &str) const { + inline bool operator !=(QStringView str) const { return !operator ==(str); } - inline bool operator >=(const QString &str) const { + inline bool operator >=(QStringView str) const { // ### return toString() >= str; } @@ -292,18 +314,34 @@ public: return byteSize() <= maxSize; } - inline Latin1String &operator=(const QString &str) + inline Latin1String &operator=(QStringView str) { int len = d->length = str.length(); uchar *l = (uchar *)d->latin1; - const ushort *uc = (const ushort *)str.unicode(); + const ushort *uc = (const ushort *)str.utf16(); qt_to_latin1_unchecked(l, uc, len); - for ( ; (quintptr)(l+len) & 0x3; ++len) - l[len] = 0; + fillTrailingZeros(); return *this; } + inline Latin1String &operator=(QLatin1String str) + { + int len = d->length = str.size(); + uchar *l = (uchar *)d->latin1; + memcpy(l, str.data(), len); + + fillTrailingZeros(); + return *this; + } + + void fillTrailingZeros() + { + uchar *l = (uchar *)d->latin1; + for (int len = d->length; (quintptr)(l + len) & 0x3; ++len) + l[len] = 0; + } + QLatin1String toQLatin1String() const noexcept { return QLatin1String(d->latin1, d->length); } @@ -351,11 +389,11 @@ public: { \ return lhs.toQLatin1String() op rhs; \ } \ - inline bool operator op(const QString &lhs, Latin1String rhs) noexcept \ + inline bool operator op(QStringView lhs, Latin1String rhs) noexcept \ { \ return lhs op rhs.toQLatin1String(); \ } \ - inline bool operator op(Latin1String lhs, const QString &rhs) noexcept \ + inline bool operator op(Latin1String lhs, QStringView rhs) noexcept \ { \ return lhs.toQLatin1String() op rhs; \ } \ @@ -419,7 +457,8 @@ inline bool String::operator<(const Latin1String &str) const } -static inline void copyString(char *dest, const QString &str, bool compress) +template <typename T> +static inline void copyString(char *dest, T str, bool compress) { if (compress) { Latin1String string(dest); @@ -469,7 +508,7 @@ public: Entry *entryAt(int i) const { return reinterpret_cast<Entry *>(((char *)this) + table()[i]); } - int indexOf(const QString &key, bool *exists) const; + int indexOf(QStringView key, bool *exists) const; int indexOf(QLatin1String key, bool *exists) const; bool isValid(int maxSize) const; @@ -577,9 +616,9 @@ public: return shallowKey().isValid(maxSize); } - bool operator ==(const QString &key) const; - inline bool operator !=(const QString &key) const { return !operator ==(key); } - inline bool operator >=(const QString &key) const; + bool operator ==(QStringView key) const; + inline bool operator !=(QStringView key) const { return !operator ==(key); } + inline bool operator >=(QStringView key) const; bool operator==(QLatin1String key) const; inline bool operator!=(QLatin1String key) const { return !operator ==(key); } @@ -589,7 +628,7 @@ public: bool operator >=(const Entry &other) const; }; -inline bool Entry::operator >=(const QString &key) const +inline bool Entry::operator >=(QStringView key) const { if (value.latinKey) return (shallowLatin1Key() >= key); @@ -602,10 +641,10 @@ inline bool Entry::operator >=(QLatin1String key) const if (value.latinKey) return shallowLatin1Key() >= key; else - return shallowKey() >= key; + return shallowKey() >= QString(key); // ### conversion to QString } -inline bool operator <(const QString &key, const Entry &e) +inline bool operator <(QStringView key, const Entry &e) { return e >= key; } inline bool operator<(QLatin1String key, const Entry &e) diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp index 6b327619ad..9636ac5856 100644 --- a/src/corelib/serialization/qjsonarray.cpp +++ b/src/corelib/serialization/qjsonarray.cpp @@ -845,7 +845,7 @@ bool QJsonArray::operator!=(const QJsonArray &other) const The return value is of type QJsonValueRef, a helper class for QJsonArray and QJsonObject. When you get an object of type QJsonValueRef, you can use it as if it were a reference to a QJsonValue. If you assign to it, - the assignment will apply to the character in the QJsonArray of QJsonObject + the assignment will apply to the element in the QJsonArray or QJsonObject from which you got the reference. \sa operator+() diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp index e0c390f610..d6a0c8c48a 100644 --- a/src/corelib/serialization/qjsoncbor.cpp +++ b/src/corelib/serialization/qjsoncbor.cpp @@ -421,7 +421,7 @@ QJsonArray QCborArray::toJsonArray() const } /*! - Recursively converts every \l QCborValue value in this array to JSON using + Recursively converts every \l QCborValue value in this map to JSON using QCborValue::toJsonValue() and creates a string key for all keys that aren't strings, then returns the corresponding QJsonObject composed of those associations. diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp index f8027efb58..193b80ee22 100644 --- a/src/corelib/serialization/qjsondocument.cpp +++ b/src/corelib/serialization/qjsondocument.cpp @@ -544,6 +544,7 @@ void QJsonDocument::setArray(const QJsonArray &array) d->ref.ref(); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -558,6 +559,16 @@ void QJsonDocument::setArray(const QJsonArray &array) */ const QJsonValue QJsonDocument::operator[](const QString &key) const { + return (*this)[QStringView(key)]; +} +#endif + +/*! + \overload + \since 5.14 +*/ +const QJsonValue QJsonDocument::operator[](QStringView key) const +{ if (!isObject()) return QJsonValue(QJsonValue::Undefined); diff --git a/src/corelib/serialization/qjsondocument.h b/src/corelib/serialization/qjsondocument.h index a8006a6cc5..a8e7485f5d 100644 --- a/src/corelib/serialization/qjsondocument.h +++ b/src/corelib/serialization/qjsondocument.h @@ -146,7 +146,10 @@ public: void setObject(const QJsonObject &object); void setArray(const QJsonArray &array); +#if QT_STRINGVIEW_LEVEL < 2 const QJsonValue operator[](const QString &key) const; +#endif + const QJsonValue operator[](QStringView key) const; const QJsonValue operator[](QLatin1String key) const; const QJsonValue operator[](int i) const; diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index c1a6328b2f..329bc4d2c9 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -377,6 +377,7 @@ bool QJsonObject::isEmpty() const return !o->length; } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -386,14 +387,17 @@ bool QJsonObject::isEmpty() const */ QJsonValue QJsonObject::value(const QString &key) const { - if (!d) - return QJsonValue(QJsonValue::Undefined); + return value(QStringView(key)); +} +#endif - bool keyExists; - int i = o->indexOf(key, &keyExists); - if (!keyExists) - return QJsonValue(QJsonValue::Undefined); - return QJsonValue(d, o, o->entryAt(i)->value); +/*! + \overload + \since 5.14 +*/ +QJsonValue QJsonObject::value(QStringView key) const +{ + return valueImpl(key); } /*! @@ -402,6 +406,15 @@ QJsonValue QJsonObject::value(const QString &key) const */ QJsonValue QJsonObject::value(QLatin1String key) const { + return valueImpl(key); +} + +/*! + \internal +*/ +template <typename T> +QJsonValue QJsonObject::valueImpl(T key) const +{ if (!d) return QJsonValue(QJsonValue::Undefined); @@ -412,6 +425,7 @@ QJsonValue QJsonObject::value(QLatin1String key) const return QJsonValue(d, o, o->entryAt(i)->value); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -423,8 +437,16 @@ QJsonValue QJsonObject::value(QLatin1String key) const */ QJsonValue QJsonObject::operator [](const QString &key) const { - return value(key); + return (*this)[QStringView(key)]; } +#endif + +/*! + \fn QJsonValue QJsonObject::operator [](QStringView key) const + + \overload + \since 5.14 +*/ /*! \fn QJsonValue QJsonObject::operator [](QLatin1String key) const @@ -433,6 +455,7 @@ QJsonValue QJsonObject::operator [](const QString &key) const \since 5.7 */ +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a reference to the value for \a key. @@ -446,14 +469,17 @@ QJsonValue QJsonObject::operator [](const QString &key) const */ QJsonValueRef QJsonObject::operator [](const QString &key) { - // ### somewhat inefficient, as we lookup the key twice if it doesn't yet exist - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : -1; - if (!keyExists) { - iterator i = insert(key, QJsonValue()); - index = i.i; - } - return QJsonValueRef(this, index); + return (*this)[QStringView(key)]; +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonValueRef QJsonObject::operator [](QStringView key) +{ + return atImpl(key); } /*! @@ -462,10 +488,25 @@ QJsonValueRef QJsonObject::operator [](const QString &key) */ QJsonValueRef QJsonObject::operator [](QLatin1String key) { - // ### optimize me - return operator[](QString(key)); + return atImpl(key); +} + +/*! + \internal +*/ +template <typename T> +QJsonValueRef QJsonObject::atImpl(T key) +{ + bool keyExists = false; + int index = o ? o->indexOf(key, &keyExists) : 0; + if (!keyExists) { + iterator i = insertAt(index, key, QJsonValue(), false); + index = i.i; + } + return QJsonValueRef(this, index); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Inserts a new item with the key \a key and a value of \a value. @@ -481,10 +522,49 @@ QJsonValueRef QJsonObject::operator [](QLatin1String key) */ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value) { + return insert(QStringView(key), value); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &value) +{ + return insertImpl(key, value); +} + +/*! + \overload + \since 5.14 +*/ +QJsonObject::iterator QJsonObject::insert(QLatin1String key, const QJsonValue &value) +{ + return insertImpl(key, value); +} + +/*! + \internal +*/ +template <typename T> +QJsonObject::iterator QJsonObject::insertImpl(T key, const QJsonValue &value) +{ if (value.t == QJsonValue::Undefined) { remove(key); return end(); } + bool keyExists = false; + int pos = o ? o->indexOf(key, &keyExists) : 0; + return insertAt(pos, key, value, keyExists); +} + +/*! + \internal + */ +template <typename T> +QJsonObject::iterator QJsonObject::insertAt(int pos, T key, const QJsonValue &value, bool keyExists) +{ QJsonValue val = value; bool latinOrIntValue; @@ -500,8 +580,6 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & if (!o->length) o->tableOffset = sizeof(QJsonPrivate::Object); - bool keyExists = false; - int pos = o->indexOf(key, &keyExists); if (keyExists) ++d->compactionCounter; @@ -518,12 +596,12 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & if (valueSize) QJsonPrivate::Value::copyData(val, (char *)e + valueOffset, latinOrIntValue); - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + compactIfNeeded(); return iterator(this, pos); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Removes \a key from the object. @@ -531,6 +609,34 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & */ void QJsonObject::remove(const QString &key) { + remove(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +void QJsonObject::remove(QStringView key) +{ + removeImpl(key); +} + +/*! + \overload + \since 5.14 +*/ +void QJsonObject::remove(QLatin1String key) +{ + removeImpl(key); +} + +/*! + \internal +*/ +template <typename T> +void QJsonObject::removeImpl(T key) +{ if (!d) return; @@ -539,13 +645,10 @@ void QJsonObject::remove(const QString &key) if (!keyExists) return; - detach2(); - o->removeItems(index, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + removeAt(index); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Removes \a key from the object. @@ -557,6 +660,34 @@ void QJsonObject::remove(const QString &key) */ QJsonValue QJsonObject::take(const QString &key) { + return take(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonValue QJsonObject::take(QStringView key) +{ + return takeImpl(key); +} + +/*! + \overload + \since 5.14 +*/ +QJsonValue QJsonObject::take(QLatin1String key) +{ + return takeImpl(key); +} + +/*! + \internal +*/ +template <typename T> +QJsonValue QJsonObject::takeImpl(T key) +{ if (!o) return QJsonValue(QJsonValue::Undefined); @@ -566,15 +697,12 @@ QJsonValue QJsonObject::take(const QString &key) return QJsonValue(QJsonValue::Undefined); QJsonValue v(d, o, o->entryAt(index)->value); - detach2(); - o->removeItems(index, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + removeAt(index); return v; } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns \c true if the object contains key \a key. @@ -582,12 +710,17 @@ QJsonValue QJsonObject::take(const QString &key) */ bool QJsonObject::contains(const QString &key) const { - if (!o) - return false; + return contains(QStringView(key)); +} +#endif - bool keyExists; - o->indexOf(key, &keyExists); - return keyExists; +/*! + \overload + \since 5.14 +*/ +bool QJsonObject::contains(QStringView key) const +{ + return containsImpl(key); } /*! @@ -596,6 +729,15 @@ bool QJsonObject::contains(const QString &key) const */ bool QJsonObject::contains(QLatin1String key) const { + return containsImpl(key); +} + +/*! + \internal +*/ +template <typename T> +bool QJsonObject::containsImpl(T key) const +{ if (!o) return false; @@ -652,15 +794,13 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) int index = it.i; - o->removeItems(index, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + removeAt(index); // iterator hasn't changed return it; } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns an iterator pointing to the item with key \a key in the map. @@ -670,12 +810,17 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) */ QJsonObject::iterator QJsonObject::find(const QString &key) { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) - return end(); - detach2(); - return iterator(this, index); + return find(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonObject::iterator QJsonObject::find(QStringView key) +{ + return findImpl(key); } /*! @@ -684,6 +829,15 @@ QJsonObject::iterator QJsonObject::find(const QString &key) */ QJsonObject::iterator QJsonObject::find(QLatin1String key) { + return findImpl(key); +} + +/*! + \internal +*/ +template <typename T> +QJsonObject::iterator QJsonObject::findImpl(T key) +{ bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; if (!keyExists) @@ -692,10 +846,18 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key) return iterator(this, index); } +#if QT_STRINGVIEW_LEVEL < 2 /*! \fn QJsonObject::const_iterator QJsonObject::find(const QString &key) const \overload */ +#endif + +/*! \fn QJsonObject::const_iterator QJsonObject::find(QStringView key) const + + \overload + \since 5.14 +*/ /*! \fn QJsonObject::const_iterator QJsonObject::find(QLatin1String key) const @@ -703,6 +865,7 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key) \since 5.7 */ +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a const iterator pointing to the item with key \a key in the map. @@ -712,11 +875,17 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key) */ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) - return end(); - return const_iterator(this, index); + return constFind(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const +{ + return constFindImpl(key); } /*! @@ -725,6 +894,15 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const */ QJsonObject::const_iterator QJsonObject::constFind(QLatin1String key) const { + return constFindImpl(key); +} + +/*! + \internal +*/ +template <typename T> +QJsonObject::const_iterator QJsonObject::constFindImpl(T key) const +{ bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; if (!keyExists) @@ -1261,6 +1439,15 @@ void QJsonObject::compact() /*! \internal */ +void QJsonObject::compactIfNeeded() +{ + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) + compact(); +} + +/*! + \internal + */ QString QJsonObject::keyAt(int i) const { Q_ASSERT(o && i >= 0 && i < (int)o->length); @@ -1289,7 +1476,21 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) Q_ASSERT(o && i >= 0 && i < (int)o->length); QJsonPrivate::Entry *e = o->entryAt(i); - insert(e->key(), val); + if (val.t == QJsonValue::Undefined) + removeAt(i); + else + insertAt(i, e->key(), val, true); +} + +/*! + \internal + */ +void QJsonObject::removeAt(int index) +{ + detach2(); + o->removeItems(index, 1); + ++d->compactionCounter; + compactIfNeeded(); } uint qHash(const QJsonObject &object, uint seed) diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index d8e2ab9ca7..05463f6f36 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -100,16 +100,28 @@ public: inline int length() const { return size(); } bool isEmpty() const; +#if QT_STRINGVIEW_LEVEL < 2 QJsonValue value(const QString &key) const; - QJsonValue value(QLatin1String key) const; QJsonValue operator[] (const QString &key) const; - QJsonValue operator[] (QLatin1String key) const { return value(key); } QJsonValueRef operator[] (const QString &key); +#endif + QJsonValue value(QStringView key) const; + QJsonValue value(QLatin1String key) const; + QJsonValue operator[] (QStringView key) const { return value(key); } + QJsonValue operator[] (QLatin1String key) const { return value(key); } + QJsonValueRef operator[] (QStringView key); QJsonValueRef operator[] (QLatin1String key); +#if QT_STRINGVIEW_LEVEL < 2 void remove(const QString &key); QJsonValue take(const QString &key); bool contains(const QString &key) const; +#endif + void remove(QStringView key); + void remove(QLatin1String key); + QJsonValue take(QStringView key); + QJsonValue take(QLatin1String key); + bool contains(QStringView key) const; bool contains(QLatin1String key) const; bool operator==(const QJsonObject &other) const; @@ -218,13 +230,20 @@ public: // more Qt typedef iterator Iterator; typedef const_iterator ConstIterator; +#if QT_STRINGVIEW_LEVEL < 2 iterator find(const QString &key); - iterator find(QLatin1String key); const_iterator find(const QString &key) const { return constFind(key); } - const_iterator find(QLatin1String key) const { return constFind(key); } const_iterator constFind(const QString &key) const; - const_iterator constFind(QLatin1String key) const; iterator insert(const QString &key, const QJsonValue &value); +#endif + iterator find(QStringView key); + iterator find(QLatin1String key); + const_iterator find(QStringView key) const { return constFind(key); } + const_iterator find(QLatin1String key) const { return constFind(key); } + const_iterator constFind(QStringView key) const; + const_iterator constFind(QLatin1String key) const; + iterator insert(QStringView key, const QJsonValue &value); + iterator insert(QLatin1String key, const QJsonValue &value); // STL compatibility typedef QJsonValue mapped_type; @@ -247,10 +266,22 @@ private: void detach(uint reserve = 0); bool detach2(uint reserve = 0); void compact(); + void compactIfNeeded(); + + template <typename T> QJsonValue valueImpl(T key) const; + template <typename T> QJsonValueRef atImpl(T key); + template <typename T> void removeImpl(T key); + template <typename T> QJsonValue takeImpl(T key); + template <typename T> bool containsImpl(T key) const; + template <typename T> iterator findImpl(T key); + template <typename T> const_iterator constFindImpl(T key) const; + template <typename T> iterator insertImpl(T key, const QJsonValue &value); QString keyAt(int i) const; QJsonValue valueAt(int i) const; void setValueAt(int i, const QJsonValue &val); + void removeAt(int i); + template <typename T> iterator insertAt(int i, T key, const QJsonValue &val, bool exists); QJsonPrivate::Data *d; QJsonPrivate::Object *o; diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp index 0bd28581f3..5f07a6a03e 100644 --- a/src/corelib/serialization/qjsonvalue.cpp +++ b/src/corelib/serialization/qjsonvalue.cpp @@ -694,6 +694,7 @@ QJsonObject QJsonValue::toObject() const return toObject(QJsonObject()); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -708,6 +709,16 @@ QJsonObject QJsonValue::toObject() const */ const QJsonValue QJsonValue::operator[](const QString &key) const { + return (*this)[QStringView(key)]; +} +#endif + +/*! + \overload + \since 5.14 +*/ +const QJsonValue QJsonValue::operator[](QStringView key) const +{ if (!isObject()) return QJsonValue(QJsonValue::Undefined); diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h index 37d84f9e60..430fa06c0f 100644 --- a/src/corelib/serialization/qjsonvalue.h +++ b/src/corelib/serialization/qjsonvalue.h @@ -137,7 +137,10 @@ public: QJsonObject toObject() const; QJsonObject toObject(const QJsonObject &defaultValue) const; +#if QT_STRINGVIEW_LEVEL < 2 const QJsonValue operator[](const QString &key) const; +#endif + const QJsonValue operator[](QStringView key) const; const QJsonValue operator[](QLatin1String key) const; const QJsonValue operator[](int i) const; diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index 9d4bc223ab..a675c3cede 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -888,7 +888,7 @@ inline bool QTextStreamPrivate::getChar(QChar *ch) if ((string && stringOffset == string->size()) || (device && readBuffer.isEmpty() && !fillReadBuffer())) { if (ch) - *ch = 0; + *ch = QChar(); return false; } if (ch) diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index be3a476cb2..500e0aa6be 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -782,8 +782,8 @@ QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack() tagStackStringStorage.reserve(32); tagStackStringStorageSize = 0; NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push(); - namespaceDeclaration.prefix = addToStringStorage(QStringViewLiteral("xml")); - namespaceDeclaration.namespaceUri = addToStringStorage(QStringViewLiteral("http://www.w3.org/XML/1998/namespace")); + namespaceDeclaration.prefix = addToStringStorage(u"xml"); + namespaceDeclaration.namespaceUri = addToStringStorage(u"http://www.w3.org/XML/1998/namespace"); initialTagStackStringStorageSize = tagStackStringStorageSize; } @@ -1423,7 +1423,7 @@ inline int QXmlStreamReaderPrivate::fastScanNMTOKEN() int n = 0; uint c; while ((c = getChar()) != StreamEOF) { - if (fastDetermineNameChar(c) == NotName) { + if (fastDetermineNameChar(QChar(c)) == NotName) { putChar(c); return n; } else { |