mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-02 13:48:05 -06:00
QJson: update to 5e3b9b84b225f4612e09ef05aa6d8c23379e4e71
This commit is contained in:
committed by
sledgehammer999
parent
1c1917f885
commit
89bd0e4397
@@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright (C) 2009 Till Adam <adam@kde.org>
|
||||
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
|
||||
* Copyright (C) 2016 Anton Kudryavtsev <a.kudryavtsev@netris.ru>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -24,7 +25,12 @@
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <cmath>
|
||||
// cmath does #undef for isnan and isinf macroses what can be defined in math.h
|
||||
#if defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_SOLARIS)
|
||||
# include <math.h>
|
||||
#else
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_SOLARIS
|
||||
# ifndef isinf
|
||||
@@ -51,10 +57,13 @@ class Serializer::SerializerPrivate {
|
||||
bool specialNumbersAllowed;
|
||||
IndentMode indentMode;
|
||||
int doublePrecision;
|
||||
QByteArray buildIndent(int spaces);
|
||||
|
||||
QByteArray serialize( const QVariant &v, bool *ok, int indentLevel = 0);
|
||||
QString sanitizeString( QString str );
|
||||
QByteArray join( const QList<QByteArray>& list, const QByteArray& sep );
|
||||
|
||||
static QByteArray buildIndent(int spaces);
|
||||
static QByteArray escapeString( const QString& str );
|
||||
static QByteArray join( const QList<QByteArray>& list, const QByteArray& sep );
|
||||
static QByteArray join( const QList<QByteArray>& list, char sep );
|
||||
};
|
||||
|
||||
QByteArray Serializer::SerializerPrivate::join( const QList<QByteArray>& list, const QByteArray& sep ) {
|
||||
@@ -67,13 +76,24 @@ QByteArray Serializer::SerializerPrivate::join( const QList<QByteArray>& list, c
|
||||
return res;
|
||||
}
|
||||
|
||||
QByteArray Serializer::SerializerPrivate::join( const QList<QByteArray>& list, char sep ) {
|
||||
QByteArray res;
|
||||
Q_FOREACH( const QByteArray& i, list ) {
|
||||
if ( !res.isEmpty() )
|
||||
res += sep;
|
||||
res += i;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok, int indentLevel)
|
||||
{
|
||||
QByteArray str;
|
||||
const QVariant::Type type = v.type();
|
||||
|
||||
if ( ! v.isValid() ) { // invalid or null?
|
||||
str = "null";
|
||||
} else if (( v.type() == QVariant::List ) || ( v.type() == QVariant::StringList )){ // an array or a stringlist?
|
||||
} else if (( type == QVariant::List ) || ( type == QVariant::StringList )) { // an array or a stringlist?
|
||||
const QVariantList list = v.toList();
|
||||
QList<QByteArray> values;
|
||||
Q_FOREACH( const QVariant& var, list )
|
||||
@@ -101,22 +121,21 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
|
||||
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull ) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str = indent + "[\n" + join( values, ",\n" ) + "\n" + indent + "]";
|
||||
str = indent + "[\n" + join( values, ",\n" ) + '\n' + indent + ']';
|
||||
}
|
||||
else if (indentMode == QJson::IndentMinimum) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str = indent + "[\n" + join( values, ",\n" ) + "\n" + indent + "]";
|
||||
str = indent + "[\n" + join( values, ",\n" ) + '\n' + indent + ']';
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str = "[" + join( values, "," ) + "]";
|
||||
str = '[' + join( values, "," ) + ']';
|
||||
}
|
||||
else {
|
||||
str = "[ " + join( values, ", " ) + " ]";
|
||||
}
|
||||
|
||||
} else if ( v.type() == QVariant::Map ) { // variant is a map?
|
||||
} else if ( type == QVariant::Map ) { // variant is a map?
|
||||
const QVariantMap vmap = v.toMap();
|
||||
QMapIterator<QString, QVariant> it( vmap );
|
||||
|
||||
if (indentMode == QJson::IndentMinimum) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
@@ -135,18 +154,17 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
}
|
||||
|
||||
QList<QByteArray> pairs;
|
||||
while ( it.hasNext() ) {
|
||||
it.next();
|
||||
for (QVariantMap::const_iterator it = vmap.begin(), end = vmap.end(); it != end; ++it) {
|
||||
indentLevel++;
|
||||
QByteArray serializedValue = serialize( it.value(), ok, indentLevel);
|
||||
indentLevel--;
|
||||
if ( !*ok ) {
|
||||
break;
|
||||
}
|
||||
QByteArray key = sanitizeString( it.key() ).toUtf8();
|
||||
QByteArray key = escapeString( it.key() );
|
||||
QByteArray value = serializedValue.trimmed();
|
||||
if (indentMode == QJson::IndentCompact) {
|
||||
pairs << key + ":" + value;
|
||||
pairs << key + ':' + value;
|
||||
} else {
|
||||
pairs << key + " : " + value;
|
||||
}
|
||||
@@ -157,7 +175,7 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
str += join( pairs, ",\n" + indent);
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += join( pairs, "," );
|
||||
str += join( pairs, ',' );
|
||||
}
|
||||
else {
|
||||
str += join( pairs, ", " );
|
||||
@@ -165,18 +183,17 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
|
||||
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str += "\n" + indent + "}";
|
||||
str += '\n' + indent + '}';
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += "}";
|
||||
str += '}';
|
||||
}
|
||||
else {
|
||||
str += " }";
|
||||
}
|
||||
|
||||
} else if ( v.type() == QVariant::Hash ) { // variant is a hash?
|
||||
} else if ( type == QVariant::Hash ) { // variant is a hash?
|
||||
const QVariantHash vhash = v.toHash();
|
||||
QHashIterator<QString, QVariant> it( vhash );
|
||||
|
||||
if (indentMode == QJson::IndentMinimum) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
@@ -195,18 +212,16 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
}
|
||||
|
||||
QList<QByteArray> pairs;
|
||||
while ( it.hasNext() ) {
|
||||
it.next();
|
||||
|
||||
for (QVariantHash::const_iterator it = vhash.begin(), end = vhash.end(); it != end; ++it) {
|
||||
QByteArray serializedValue = serialize( it.value(), ok, indentLevel + 1);
|
||||
|
||||
if ( !*ok ) {
|
||||
break;
|
||||
}
|
||||
QByteArray key = sanitizeString( it.key() ).toUtf8();
|
||||
QByteArray key = escapeString( it.key() );
|
||||
QByteArray value = serializedValue.trimmed();
|
||||
if (indentMode == QJson::IndentCompact) {
|
||||
pairs << key + ":" + value;
|
||||
pairs << key + ':' + value;
|
||||
} else {
|
||||
pairs << key + " : " + value;
|
||||
}
|
||||
@@ -217,7 +232,7 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
str += join( pairs, ",\n" + indent);
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += join( pairs, "," );
|
||||
str += join( pairs, ',' );
|
||||
}
|
||||
else {
|
||||
str += join( pairs, ", " );
|
||||
@@ -225,10 +240,10 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
|
||||
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str += "\n" + indent + "}";
|
||||
str += '\n' + indent + '}';
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += "}";
|
||||
str += '}';
|
||||
}
|
||||
else {
|
||||
str += " }";
|
||||
@@ -248,9 +263,9 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
break;
|
||||
}
|
||||
|
||||
if (( v.type() == QVariant::String ) || ( v.type() == QVariant::ByteArray )) { // a string or a byte array?
|
||||
str = sanitizeString( v.toString() ).toUtf8();
|
||||
} else if (( v.type() == QVariant::Double) || ((QMetaType::Type)v.type() == QMetaType::Float)) { // a double or a float?
|
||||
if (( type == QVariant::String ) || ( type == QVariant::ByteArray )) { // a string or a byte array?
|
||||
str += escapeString( v.toString() );
|
||||
} else if (( type == QVariant::Double) || ((QMetaType::Type)type == QMetaType::Float)) { // a double or a float?
|
||||
const double value = v.toDouble();
|
||||
#if defined _WIN32 && !defined(Q_OS_SYMBIAN)
|
||||
const bool special = _isnan(value) || !_finite(value);
|
||||
@@ -281,15 +296,15 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
}
|
||||
} else {
|
||||
str = QByteArray::number( value , 'g', doublePrecision);
|
||||
if( ! str.contains( "." ) && ! str.contains( "e" ) ) {
|
||||
if( !str.contains( '.' ) && !str.contains( 'e' ) ) {
|
||||
str += ".0";
|
||||
}
|
||||
}
|
||||
} else if ( v.type() == QVariant::Bool ) { // boolean value?
|
||||
} else if ( type == QVariant::Bool ) { // boolean value?
|
||||
str += ( v.toBool() ? "true" : "false" );
|
||||
} else if ( v.type() == QVariant::ULongLong ) { // large unsigned number?
|
||||
} else if ( type == QVariant::ULongLong ) { // large unsigned number?
|
||||
str += QByteArray::number( v.value<qulonglong>() );
|
||||
} else if ( v.type() == QVariant::UInt ) { // unsigned int number?
|
||||
} else if ( type == QVariant::UInt ) { // unsigned int number?
|
||||
str += QByteArray::number( v.value<quint32>() );
|
||||
} else if ( v.canConvert<qlonglong>() ) { // any signed number?
|
||||
str += QByteArray::number( v.value<qlonglong>() );
|
||||
@@ -297,7 +312,7 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
|
||||
str += QByteArray::number( v.value<int>() );
|
||||
} else if ( v.canConvert<QString>() ){ // can value be converted to string?
|
||||
// this will catch QDate, QDateTime, QUrl, ...
|
||||
str += sanitizeString( v.toString() ).toUtf8();
|
||||
str += escapeString( v.toString() );
|
||||
//TODO: catch other values like QImage, QRect, ...
|
||||
} else {
|
||||
*ok = false;
|
||||
@@ -323,42 +338,52 @@ QByteArray Serializer::SerializerPrivate::buildIndent(int spaces)
|
||||
spaces = 0;
|
||||
}
|
||||
for (int i = 0; i < spaces; i++ ) {
|
||||
indent += " ";
|
||||
indent += ' ';
|
||||
}
|
||||
return indent;
|
||||
}
|
||||
|
||||
QString Serializer::SerializerPrivate::sanitizeString( QString str )
|
||||
QByteArray Serializer::SerializerPrivate::escapeString( const QString& str )
|
||||
{
|
||||
str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) );
|
||||
|
||||
// escape unicode chars
|
||||
QString result;
|
||||
const ushort* unicode = str.utf16();
|
||||
unsigned int i = 0;
|
||||
|
||||
while ( unicode[ i ] ) {
|
||||
if ( unicode[ i ] < 128 ) {
|
||||
result.append( QChar( unicode[ i ] ) );
|
||||
QByteArray result;
|
||||
result.reserve(str.size() + 2);
|
||||
result.append('\"');
|
||||
for (QString::const_iterator it = str.begin(), end = str.end(); it != end; ++it) {
|
||||
ushort unicode = it->unicode();
|
||||
switch ( unicode ) {
|
||||
case '\"':
|
||||
result.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
result.append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
result.append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
result.append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
result.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
result.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
result.append("\\t");
|
||||
break;
|
||||
default:
|
||||
if ( unicode > 0x1F && unicode < 128 ) {
|
||||
result.append(static_cast<char>(unicode));
|
||||
} else {
|
||||
char escaped[7];
|
||||
qsnprintf(escaped, sizeof(escaped)/sizeof(char), "\\u%04x", unicode);
|
||||
result.append(escaped);
|
||||
}
|
||||
}
|
||||
else {
|
||||
QString hexCode = QString::number( unicode[ i ], 16 ).rightJustified( 4,
|
||||
QLatin1Char('0') );
|
||||
|
||||
result.append( QLatin1String ("\\u") ).append( hexCode );
|
||||
}
|
||||
++i;
|
||||
}
|
||||
str = result;
|
||||
|
||||
str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
|
||||
str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) );
|
||||
str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) );
|
||||
str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) );
|
||||
str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) );
|
||||
str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) );
|
||||
|
||||
return QString( QLatin1String( "\"%1\"" ) ).arg( str );
|
||||
result.append('\"');
|
||||
return result;
|
||||
}
|
||||
|
||||
Serializer::Serializer()
|
||||
|
||||
Reference in New Issue
Block a user