diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/serialization/qjson_p.h | 61 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonobject.cpp | 148 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonobject.h | 14 |
3 files changed, 179 insertions, 44 deletions
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 78082a920d..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; } +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(QStringView 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); @@ -218,11 +228,29 @@ public: { d->length = str.length(); qToLittleEndian<quint16>(str.utf16(), str.length(), d->utf16); - if (str.length() & 1) - d->utf16[str.length()] = 0; + fillTrailingZeros(); return *this; } + inline String &operator=(QLatin1String str) + { + d->length = str.size(); +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + for (int i = 0; i < str.size(); ++i) + d->utf16[i] = str[i].unicode(); +#else + qt_from_latin1((ushort *)d->utf16, str.data(), str.size()); +#endif + fillTrailingZeros(); + return *this; + } + + 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; @@ -293,11 +321,27 @@ public: 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); } @@ -413,7 +457,8 @@ inline bool String::operator<(const Latin1String &str) const } -static inline void copyString(char *dest, QStringView str, bool compress) +template <typename T> +static inline void copyString(char *dest, T str, bool compress) { if (compress) { Latin1String string(dest); diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index 19a16d8537..99ab25f265 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -397,14 +397,7 @@ QJsonValue QJsonObject::value(const QString &key) const */ QJsonValue QJsonObject::value(QStringView key) const { - if (!d) - return QJsonValue(QJsonValue::Undefined); - - bool keyExists; - int i = o->indexOf(key, &keyExists); - if (!keyExists) - return QJsonValue(QJsonValue::Undefined); - return QJsonValue(d, o, o->entryAt(i)->value); + return valueImpl(key); } /*! @@ -413,6 +406,15 @@ QJsonValue QJsonObject::value(QStringView 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); @@ -477,13 +479,7 @@ QJsonValueRef QJsonObject::operator [](const QString &key) */ QJsonValueRef QJsonObject::operator [](QStringView 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); + return atImpl(key); } /*! @@ -492,8 +488,22 @@ QJsonValueRef QJsonObject::operator [](QStringView 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 @@ -522,6 +532,24 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & */ 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(); @@ -534,7 +562,8 @@ QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &val /*! \internal */ -QJsonObject::iterator QJsonObject::insertAt(int pos, QStringView key, const QJsonValue &value, bool keyExists) +template <typename T> +QJsonObject::iterator QJsonObject::insertAt(int pos, T key, const QJsonValue &value, bool keyExists) { QJsonValue val = value; @@ -590,6 +619,24 @@ void QJsonObject::remove(const QString &key) */ 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; @@ -623,6 +670,24 @@ QJsonValue QJsonObject::take(const QString &key) */ 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); @@ -655,12 +720,7 @@ bool QJsonObject::contains(const QString &key) const */ bool QJsonObject::contains(QStringView key) const { - if (!o) - return false; - - bool keyExists; - o->indexOf(key, &keyExists); - return keyExists; + return containsImpl(key); } /*! @@ -669,6 +729,15 @@ bool QJsonObject::contains(QStringView 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; @@ -751,12 +820,7 @@ QJsonObject::iterator QJsonObject::find(const QString &key) */ QJsonObject::iterator QJsonObject::find(QStringView key) { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) - return end(); - detach2(); - return iterator(this, index); + return findImpl(key); } /*! @@ -765,6 +829,15 @@ QJsonObject::iterator QJsonObject::find(QStringView 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) @@ -812,11 +885,7 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const */ QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) - return end(); - return const_iterator(this, index); + return constFindImpl(key); } /*! @@ -825,6 +894,15 @@ QJsonObject::const_iterator QJsonObject::constFind(QStringView 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) diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index bdaf85b460..05463f6f36 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -118,7 +118,9 @@ public: 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; @@ -241,6 +243,7 @@ public: 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; @@ -265,11 +268,20 @@ private: 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); - iterator insertAt(int i, QStringView key, const QJsonValue &val, bool exists); + template <typename T> iterator insertAt(int i, T key, const QJsonValue &val, bool exists); QJsonPrivate::Data *d; QJsonPrivate::Object *o; |