diff options
Diffstat (limited to 'src/corelib/serialization/qbinaryjson_p.h')
-rw-r--r-- | src/corelib/serialization/qbinaryjson_p.h | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/src/corelib/serialization/qbinaryjson_p.h b/src/corelib/serialization/qbinaryjson_p.h index 132c36f227..6502f1fbd2 100644 --- a/src/corelib/serialization/qbinaryjson_p.h +++ b/src/corelib/serialization/qbinaryjson_p.h @@ -136,11 +136,15 @@ using qle_ushort = q_littleendian<unsigned short>; using qle_int = q_littleendian<int>; using qle_uint = q_littleendian<unsigned int>; -template<int pos, int width> -using qle_bitfield = QLEIntegerBitfield<uint, pos, width>; +template<typename... Accessors> +using qle_bitfield = QLEIntegerBitfieldUnion<uint, Accessors...>; template<int pos, int width> -using qle_signedbitfield = QLEIntegerBitfield<int, pos, width>; +using qle_bitfield_accessor + = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width>; +template<int pos, int width> +using qle_signedbitfield_accessor + = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width, int>; using offset = qle_uint; @@ -316,19 +320,24 @@ static inline void copyString(char *dest, QStringView str, bool compress) */ class Base { +private: + using IsObjectAccessor = qle_bitfield_accessor<0, 1>; + using LengthAccessor = qle_bitfield_accessor<1, 31>; public: qle_uint size; - union { - uint _dummy; - qle_bitfield<0, 1> is_object; - qle_bitfield<1, 31> length; - }; + qle_bitfield<IsObjectAccessor, LengthAccessor> isObjectAndLength; offset tableOffset; // content follows here - bool isObject() const { return !!is_object; } + void setIsObject() { isObjectAndLength.set<IsObjectAccessor>(1); } + bool isObject() const { return !!isObjectAndLength.get<IsObjectAccessor>(); } + + void setIsArray() { isObjectAndLength.set<IsObjectAccessor>(0); } bool isArray() const { return !isObject(); } + void setLength(uint length) { isObjectAndLength.set<LengthAccessor>(length); } + uint length() const { return isObjectAndLength.get<LengthAccessor>(); } + offset *table() { return reinterpret_cast<offset *>(reinterpret_cast<char *>(this) + tableOffset); @@ -372,39 +381,46 @@ public: class Value { +private: + using TypeAccessor = qle_bitfield_accessor<0, 3>; + using LatinOrIntValueAccessor = qle_bitfield_accessor<3, 1>; + using LatinKeyAccessor = qle_bitfield_accessor<4, 1>; + using ValueAccessor = qle_bitfield_accessor<5, 27>; + using IntValueAccessor = qle_signedbitfield_accessor<5, 27>; + qle_bitfield< + TypeAccessor, + LatinOrIntValueAccessor, + LatinKeyAccessor, + ValueAccessor, + IntValueAccessor + > m_data; + int intValue() const { return m_data.get<IntValueAccessor>(); } + public: enum { MaxSize = (1 << 27) - 1 }; - union { - uint _dummy; - qle_bitfield<0, 3> type; - qle_bitfield<3, 1> latinOrIntValue; - qle_bitfield<4, 1> latinKey; - qle_bitfield<5, 27> value; - qle_signedbitfield<5, 27> int_value; - }; inline const char *data(const Base *b) const { - return reinterpret_cast<const char *>(b) + value; + return reinterpret_cast<const char *>(b) + value(); } uint usedStorage(const Base *b) const; bool toBoolean() const { - Q_ASSERT(type == QJsonValue::Bool); - return value != 0; + Q_ASSERT(type() == QJsonValue::Bool); + return value() != 0; } double toDouble(const Base *b) const { - Q_ASSERT(type == QJsonValue::Double); - if (latinOrIntValue) - return int_value; + Q_ASSERT(type() == QJsonValue::Double); + if (isLatinOrIntValue()) + return intValue(); - auto i = qFromLittleEndian<quint64>(reinterpret_cast<const uchar *>(b) + value); + auto i = qFromLittleEndian<quint64>(reinterpret_cast<const uchar *>(b) + value()); double d; memcpy(&d, &i, sizeof(double)); return d; @@ -412,26 +428,26 @@ public: QString toString(const Base *b) const { - return latinOrIntValue + return isLatinOrIntValue() ? asLatin1String(b).toString() : asString(b).toString(); } String asString(const Base *b) const { - Q_ASSERT(type == QJsonValue::String && !latinOrIntValue); + Q_ASSERT(type() == QJsonValue::String && !isLatinOrIntValue()); return String(data(b)); } Latin1String asLatin1String(const Base *b) const { - Q_ASSERT(type == QJsonValue::String && latinOrIntValue); + Q_ASSERT(type() == QJsonValue::String && isLatinOrIntValue()); return Latin1String(data(b)); } const Base *base(const Base *b) const { - Q_ASSERT(type == QJsonValue::Array || type == QJsonValue::Object); + Q_ASSERT(type() == QJsonValue::Array || type() == QJsonValue::Object); return reinterpret_cast<const Base *>(data(b)); } @@ -441,6 +457,15 @@ public: static uint requiredStorage(const QBinaryJsonValue &v, bool *compressed); static uint valueToStore(const QBinaryJsonValue &v, uint offset); static void copyData(const QBinaryJsonValue &v, char *dest, bool compressed); + + void setIsLatinKey(bool isLatinKey) { m_data.set<LatinKeyAccessor>(isLatinKey); } + bool isLatinKey() const { return m_data.get<LatinKeyAccessor>(); } + void setIsLatinOrIntValue(bool v) { m_data.set<LatinOrIntValueAccessor>(v); } + bool isLatinOrIntValue() const { return m_data.get<LatinOrIntValueAccessor>(); } + void setType(uint type) { m_data.set<TypeAccessor>(type); } + uint type() const { return m_data.get<TypeAccessor>(); } + void setValue(uint value) { m_data.set<ValueAccessor>(value); } + uint value() const { return m_data.get<ValueAccessor>(); } }; class Entry { @@ -452,7 +477,7 @@ public: uint size() const { uint s = sizeof(Entry); - if (value.latinKey) + if (value.isLatinKey()) s += shallowLatin1Key().byteSize(); else s += shallowKey().byteSize(); @@ -466,19 +491,19 @@ public: String shallowKey() const { - Q_ASSERT(!value.latinKey); + Q_ASSERT(!value.isLatinKey()); return String(reinterpret_cast<const char *>(this) + sizeof(Entry)); } Latin1String shallowLatin1Key() const { - Q_ASSERT(value.latinKey); + Q_ASSERT(value.isLatinKey()); return Latin1String(reinterpret_cast<const char *>(this) + sizeof(Entry)); } QString key() const { - return value.latinKey + return value.isLatinKey() ? shallowLatin1Key().toString() : shallowKey().toString(); } @@ -488,21 +513,21 @@ public: if (maxSize < sizeof(Entry)) return false; maxSize -= sizeof(Entry); - return value.latinKey + return value.isLatinKey() ? shallowLatin1Key().isValid(maxSize) : shallowKey().isValid(maxSize); } bool operator ==(QStringView key) const { - return value.latinKey + return value.isLatinKey() ? (shallowLatin1Key().toQLatin1String() == key) : (shallowKey() == key); } bool operator >=(QStringView key) const { - return value.latinKey + return value.isLatinKey() ? (shallowLatin1Key().toQLatin1String() >= key) : (shallowKey().toString() >= key); } @@ -560,9 +585,12 @@ public: header->version = 1; Base *b = header->root(); b->size = sizeof(Base); - b->is_object = (valueType == QJsonValue::Object); + if (valueType == QJsonValue::Object) + b->setIsObject(); + else + b->setIsArray(); b->tableOffset = sizeof(Base); - b->length = 0; + b->setLength(0); } ~MutableData() |