Merge pull request #5896 from Chocobo1/qjson

QJson: update to latest git version
This commit is contained in:
sledgehammer999 2016-11-06 23:52:46 +02:00 committed by GitHub
commit 6302eb1317
5 changed files with 176 additions and 147 deletions

View file

@ -149,7 +149,7 @@ namespace yy {
{
if (*yystr == '"')
{
std::string yyr = "";
std::string yyr;
char const *yyp = yystr;
for (;;)
@ -471,17 +471,17 @@ namespace yy {
}
break;
case 6:
case 5:
/* Line 670 of lalr1.cc */
#line 96 "json_parser.yy"
#line 95 "json_parser.yy"
{
(yyval) = QVariant(QVariantMap());
}
break;
case 7:
case 6:
/* Line 670 of lalr1.cc */
#line 99 "json_parser.yy"
#line 98 "json_parser.yy"
{
QVariantMap* map = (yysemantic_stack_[(3) - (2)]).value<QVariantMap*>();
(yyval) = QVariant(*map);
@ -489,9 +489,9 @@ namespace yy {
}
break;
case 8:
case 7:
/* Line 670 of lalr1.cc */
#line 105 "json_parser.yy"
#line 104 "json_parser.yy"
{
QVariantMap* pair = new QVariantMap();
pair->insert((yysemantic_stack_[(3) - (1)]).toString(), (yysemantic_stack_[(3) - (3)]));
@ -499,25 +499,25 @@ namespace yy {
}
break;
case 9:
case 8:
/* Line 670 of lalr1.cc */
#line 110 "json_parser.yy"
#line 109 "json_parser.yy"
{
(yyval).value<QVariantMap*>()->insert((yysemantic_stack_[(5) - (3)]).toString(), (yysemantic_stack_[(5) - (5)]));
}
break;
case 10:
case 9:
/* Line 670 of lalr1.cc */
#line 114 "json_parser.yy"
#line 113 "json_parser.yy"
{
(yyval) = QVariant(QVariantList());
}
break;
case 11:
case 10:
/* Line 670 of lalr1.cc */
#line 117 "json_parser.yy"
#line 116 "json_parser.yy"
{
QVector<QVariant>* list = (yysemantic_stack_[(3) - (2)]).value<QVector<QVariant>* >();
(yyval) = QVariant(list->toList());
@ -525,9 +525,9 @@ namespace yy {
}
break;
case 12:
case 11:
/* Line 670 of lalr1.cc */
#line 123 "json_parser.yy"
#line 122 "json_parser.yy"
{
QVector<QVariant>* list = new QVector<QVariant>(1);
list->replace(0, (yysemantic_stack_[(1) - (1)]));
@ -535,9 +535,9 @@ namespace yy {
}
break;
case 13:
case 12:
/* Line 670 of lalr1.cc */
#line 128 "json_parser.yy"
#line 127 "json_parser.yy"
{
(yyval).value<QVector<QVariant>* >()->append((yysemantic_stack_[(3) - (3)]));
}
@ -849,10 +849,10 @@ namespace yy {
const signed char
json_parser::yypact_[] =
{
1, -5, -5, 3, 18, -5, -5, -5, -5, -5,
8, -5, -5, -5, -5, -5, 2, 11, -5, -3,
-5, -5, 29, -5, 4, -5, 29, -5, 13, -5,
29, -5
0, -5, 2, 18, -5, -5, -5, -5, -5, 7,
-5, -5, -5, -5, -5, 1, 12, -5, -4, -5,
-5, 29, -5, 4, -5, 29, -5, 26, -5, 29,
-5
};
/* YYDEFACT[S] -- default reduction number in state S. Performed when
@ -861,24 +861,24 @@ namespace yy {
const unsigned char
json_parser::yydefact_[] =
{
0, 5, 4, 0, 0, 15, 16, 17, 18, 14,
0, 2, 19, 20, 3, 6, 0, 0, 10, 0,
12, 1, 0, 7, 0, 11, 0, 8, 0, 13,
0, 9
0, 4, 0, 0, 14, 15, 16, 17, 13, 0,
2, 18, 19, 3, 5, 0, 0, 9, 0, 11,
1, 0, 6, 0, 10, 0, 7, 0, 12, 0,
8
};
/* YYPGOTO[NTERM-NUM]. */
const signed char
json_parser::yypgoto_[] =
{
-5, -5, -5, -5, -5, -5, -5, -4
-5, -5, -5, -5, -5, -5, -5, -3
};
/* YYDEFGOTO[NTERM-NUM]. */
const signed char
json_parser::yydefgoto_[] =
{
-1, 10, 11, 12, 17, 13, 19, 14
-1, 9, 10, 11, 16, 12, 18, 13
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@ -888,21 +888,21 @@ namespace yy {
const unsigned char
json_parser::yytable_[] =
{
20, 1, 2, 25, 3, 26, 4, 15, 21, 22,
5, 6, 7, 8, 9, 23, 16, 28, 27, 24,
30, 3, 29, 4, 18, 0, 31, 5, 6, 7,
8, 9, 3, 0, 4, 0, 0, 0, 5, 6,
7, 8, 9
19, 1, 24, 2, 25, 3, 14, 20, 21, 4,
5, 6, 7, 8, 0, 15, 22, 27, 26, 0,
23, 2, 28, 3, 17, 0, 30, 4, 5, 6,
7, 8, 2, 29, 3, 0, 0, 0, 4, 5,
6, 7, 8
};
/* YYCHECK. */
const signed char
json_parser::yycheck_[] =
{
4, 0, 1, 6, 3, 8, 5, 4, 0, 7,
9, 10, 11, 12, 13, 4, 13, 13, 22, 8,
7, 3, 26, 5, 6, -1, 30, 9, 10, 11,
12, 13, 3, -1, 5, -1, -1, -1, 9, 10,
3, 1, 6, 3, 8, 5, 4, 0, 7, 9,
10, 11, 12, 13, -1, 13, 4, 13, 21, -1,
8, 3, 25, 5, 6, -1, 29, 9, 10, 11,
12, 13, 3, 7, 5, -1, -1, -1, 9, 10,
11, 12, 13
};
@ -911,10 +911,10 @@ namespace yy {
const unsigned char
json_parser::yystos_[] =
{
0, 0, 1, 3, 5, 9, 10, 11, 12, 13,
16, 17, 18, 20, 22, 4, 13, 19, 6, 21,
22, 0, 7, 4, 8, 6, 8, 22, 13, 22,
7, 22
0, 1, 3, 5, 9, 10, 11, 12, 13, 16,
17, 18, 20, 22, 4, 13, 19, 6, 21, 22,
0, 7, 4, 8, 6, 8, 22, 13, 22, 7,
22
};
#if YYDEBUG
@ -932,18 +932,16 @@ namespace yy {
const unsigned char
json_parser::yyr1_[] =
{
0, 15, 16, 17, 17, 17, 18, 18, 19, 19,
20, 20, 21, 21, 22, 22, 22, 22, 22, 22,
22
0, 15, 16, 17, 17, 18, 18, 19, 19, 20,
20, 21, 21, 22, 22, 22, 22, 22, 22, 22
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
const unsigned char
json_parser::yyr2_[] =
{
0, 2, 1, 1, 1, 1, 2, 3, 3, 5,
2, 3, 1, 3, 1, 1, 1, 1, 1, 1,
1
0, 2, 1, 1, 1, 2, 3, 3, 5, 2,
3, 1, 3, 1, 1, 1, 1, 1, 1, 1
};
@ -963,12 +961,12 @@ namespace yy {
const json_parser::rhs_number_type
json_parser::yyrhs_[] =
{
16, 0, -1, 17, -1, 22, -1, 1, -1, 0,
-1, 3, 4, -1, 3, 19, 4, -1, 13, 7,
22, -1, 19, 8, 13, 7, 22, -1, 5, 6,
-1, 5, 21, 6, -1, 22, -1, 21, 8, 22,
-1, 13, -1, 9, -1, 10, -1, 11, -1, 12,
-1, 18, -1, 20, -1
16, 0, -1, 17, -1, 22, -1, 1, -1, 3,
4, -1, 3, 19, 4, -1, 13, 7, 22, -1,
19, 8, 13, 7, 22, -1, 5, 6, -1, 5,
21, 6, -1, 22, -1, 21, 8, 22, -1, 13,
-1, 9, -1, 10, -1, 11, -1, 12, -1, 18,
-1, 20, -1
};
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
@ -976,18 +974,16 @@ namespace yy {
const unsigned char
json_parser::yyprhs_[] =
{
0, 0, 3, 5, 7, 9, 11, 14, 18, 22,
28, 31, 35, 37, 41, 43, 45, 47, 49, 51,
53
0, 0, 3, 5, 7, 9, 12, 16, 20, 26,
29, 33, 35, 39, 41, 43, 45, 47, 49, 51
};
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
const unsigned char
json_parser::yyrline_[] =
{
0, 82, 82, 87, 88, 94, 96, 99, 105, 110,
114, 117, 123, 128, 132, 133, 134, 135, 136, 137,
138
0, 82, 82, 87, 88, 95, 98, 104, 109, 113,
116, 122, 127, 131, 132, 133, 134, 135, 136, 137
};
// Print the state stack on the debug stream.
@ -1064,7 +1060,7 @@ namespace yy {
const int json_parser::yylast_ = 42;
const int json_parser::yynnts_ = 8;
const int json_parser::yyempty_ = -2;
const int json_parser::yyfinal_ = 21;
const int json_parser::yyfinal_ = 20;
const int json_parser::yyterror_ = 1;
const int json_parser::yyerrcode_ = 256;
const int json_parser::yyntokens_ = 15;
@ -1075,9 +1071,9 @@ namespace yy {
} // yy
/* Line 1141 of lalr1.cc */
#line 1079 "json_parser.cc"
#line 1075 "json_parser.cc"
/* Line 1142 of lalr1.cc */
#line 140 "json_parser.yy"
#line 139 "json_parser.yy"
int yy::yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver)

View file

@ -3529,11 +3529,19 @@ YY_RULE_SETUP
return yy::json_parser::token::STRING;
}
YY_BREAK
case YY_STATE_EOF(QUOTMARK_OPEN):
#line 173 "json_scanner.yy"
{
qCritical() << "Unterminated string";
m_yylloc->columns(yyleng);
return yy::json_parser::token::INVALID;
}
YY_BREAK
case 24:
YY_RULE_SETUP
#line 175 "json_scanner.yy"
#line 182 "json_scanner.yy"
{
QString hexDigits = QString::fromUtf8(yytext, yyleng);
bool ok;
@ -3546,7 +3554,7 @@ YY_RULE_SETUP
case 25:
/* rule 25 can match eol */
YY_RULE_SETUP
#line 184 "json_scanner.yy"
#line 191 "json_scanner.yy"
{
qCritical() << "Invalid hex string";
m_yylloc->columns(yyleng);
@ -3559,7 +3567,7 @@ YY_RULE_SETUP
/* "Compound type" related tokens */
case 26:
YY_RULE_SETUP
#line 196 "json_scanner.yy"
#line 203 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::COLON;
@ -3567,7 +3575,7 @@ YY_RULE_SETUP
YY_BREAK
case 27:
YY_RULE_SETUP
#line 201 "json_scanner.yy"
#line 208 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::COMMA;
@ -3575,7 +3583,7 @@ YY_RULE_SETUP
YY_BREAK
case 28:
YY_RULE_SETUP
#line 206 "json_scanner.yy"
#line 213 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::SQUARE_BRACKET_OPEN;
@ -3583,7 +3591,7 @@ YY_RULE_SETUP
YY_BREAK
case 29:
YY_RULE_SETUP
#line 211 "json_scanner.yy"
#line 218 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::SQUARE_BRACKET_CLOSE;
@ -3591,7 +3599,7 @@ YY_RULE_SETUP
YY_BREAK
case 30:
YY_RULE_SETUP
#line 216 "json_scanner.yy"
#line 223 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::CURLY_BRACKET_OPEN;
@ -3599,7 +3607,7 @@ YY_RULE_SETUP
YY_BREAK
case 31:
YY_RULE_SETUP
#line 221 "json_scanner.yy"
#line 228 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::CURLY_BRACKET_CLOSE;
@ -3609,7 +3617,7 @@ YY_RULE_SETUP
case 32:
YY_RULE_SETUP
#line 229 "json_scanner.yy"
#line 236 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
*m_yylval = QVariant(std::numeric_limits<double>::quiet_NaN());
@ -3618,7 +3626,7 @@ YY_RULE_SETUP
YY_BREAK
case 33:
YY_RULE_SETUP
#line 235 "json_scanner.yy"
#line 242 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
*m_yylval = QVariant(std::numeric_limits<double>::infinity());
@ -3627,7 +3635,7 @@ YY_RULE_SETUP
YY_BREAK
case 34:
YY_RULE_SETUP
#line 241 "json_scanner.yy"
#line 248 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
*m_yylval = QVariant(-std::numeric_limits<double>::infinity());
@ -3638,25 +3646,24 @@ YY_RULE_SETUP
/* If all else fails */
case 35:
YY_RULE_SETUP
#line 249 "json_scanner.yy"
#line 256 "json_scanner.yy"
{
m_yylloc->columns(yyleng);
return yy::json_parser::token::INVALID;
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(QUOTMARK_OPEN):
case YY_STATE_EOF(HEX_OPEN):
case YY_STATE_EOF(ALLOW_SPECIAL_NUMBERS):
#line 254 "json_scanner.yy"
#line 261 "json_scanner.yy"
return yy::json_parser::token::END;
YY_BREAK
case 36:
YY_RULE_SETUP
#line 255 "json_scanner.yy"
#line 262 "json_scanner.yy"
ECHO;
YY_BREAK
#line 3660 "json_scanner.cc"
#line 3667 "json_scanner.cc"
case YY_END_OF_BUFFER:
{
@ -4510,4 +4517,4 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
#line 255 "json_scanner.yy"
#line 262 "json_scanner.yy"

View file

@ -1,6 +1,7 @@
/* This file is part of QJson
*
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
* 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
@ -31,9 +32,9 @@
using namespace QJson;
ParserPrivate::ParserPrivate() :
m_scanner(0)
m_scanner(0),
m_specialNumbersAllowed(false)
{
m_specialNumbersAllowed = false;
reset();
}
@ -43,7 +44,7 @@ ParserPrivate::~ParserPrivate()
delete m_scanner;
}
void ParserPrivate::setError(QString errorMsg, int errorLine) {
void ParserPrivate::setError(const QString &errorMsg, int errorLine) {
m_error = true;
m_errorMsg = errorMsg;
m_errorLine = errorLine;
@ -116,7 +117,7 @@ QVariant Parser::parse (QIODevice* io, bool* ok)
QVariant Parser::parse(const QByteArray& jsonString, bool* ok) {
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
buffer.open(QBuffer::ReadWrite | QBuffer::Text);
buffer.write(jsonString);
buffer.seek(0);
return parse (&buffer, ok);

View file

@ -43,7 +43,7 @@ namespace QJson {
void reset();
void setError(QString errorMsg, int line);
void setError(const QString &errorMsg, int line);
JSonScanner* m_scanner;
bool m_error;

View file

@ -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>
// 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()