summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qjson_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/serialization/qjson_p.h')
-rw-r--r--src/corelib/serialization/qjson_p.h113
1 files changed, 75 insertions, 38 deletions
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index ff010cb902..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,39 +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(static_cast<void *>(d->utf16),
- static_cast<const void *>(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;
}
@@ -294,19 +314,35 @@ 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;
}
- QLatin1String toQLatin1String() const Q_DECL_NOTHROW {
+ 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);
}
@@ -341,23 +377,23 @@ public:
};
#define DEF_OP(op) \
- inline bool operator op(Latin1String lhs, Latin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(Latin1String lhs, Latin1String rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs.toQLatin1String(); \
} \
- inline bool operator op(QLatin1String lhs, Latin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(QLatin1String lhs, Latin1String rhs) noexcept \
{ \
return lhs op rhs.toQLatin1String(); \
} \
- inline bool operator op(Latin1String lhs, QLatin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(Latin1String lhs, QLatin1String rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs; \
} \
- inline bool operator op(const QString &lhs, Latin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(QStringView lhs, Latin1String rhs) noexcept \
{ \
return lhs op rhs.toQLatin1String(); \
} \
- inline bool operator op(Latin1String lhs, const QString &rhs) Q_DECL_NOTHROW \
+ inline bool operator op(Latin1String lhs, QStringView rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs; \
} \
@@ -421,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);
@@ -471,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;
@@ -579,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); }
@@ -591,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);
@@ -604,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)
@@ -688,7 +725,7 @@ public:
{
}
inline Data(int reserved, QJsonValue::Type valueType)
- : rawData(0), compactionCounter(0), ownsData(true)
+ : rawData(nullptr), compactionCounter(0), ownsData(true)
{
Q_ASSERT(valueType == QJsonValue::Array || valueType == QJsonValue::Object);
@@ -721,7 +758,7 @@ public:
Data *clone(Base *b, int reserve = 0)
{
int size = sizeof(Header) + b->size;
- if (b == header->root() && ref.load() == 1 && alloc >= size + reserve)
+ if (b == header->root() && ref.loadRelaxed() == 1 && alloc >= size + reserve)
return this;
if (reserve) {
@@ -730,7 +767,7 @@ public:
size = qMax(size + reserve, qMin(size *2, (int)Value::MaxSize));
if (size > Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure");
- return 0;
+ return nullptr;
}
}
char *raw = (char *)malloc(size);