Browse Source

Merge pull request #5896 from Chocobo1/qjson

QJson: update to latest git version
adaptive-webui-19844
sledgehammer999 8 years ago committed by GitHub
parent
commit
6302eb1317
  1. 118
      src/webui/qjson/json_parser.cc
  2. 41
      src/webui/qjson/json_scanner.cc
  3. 9
      src/webui/qjson/parser.cpp
  4. 2
      src/webui/qjson/parser_p.h
  5. 153
      src/webui/qjson/serializer.cpp

118
src/webui/qjson/json_parser.cc

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

41
src/webui/qjson/json_scanner.cc

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

9
src/webui/qjson/parser.cpp

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

2
src/webui/qjson/parser_p.h

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

153
src/webui/qjson/serializer.cpp

@ -2,6 +2,7 @@
* *
* Copyright (C) 2009 Till Adam <adam@kde.org> * Copyright (C) 2009 Till Adam <adam@kde.org>
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name> * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -24,7 +25,12 @@
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QVariant> #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 #ifdef Q_OS_SOLARIS
# ifndef isinf # ifndef isinf
@ -51,10 +57,13 @@ class Serializer::SerializerPrivate {
bool specialNumbersAllowed; bool specialNumbersAllowed;
IndentMode indentMode; IndentMode indentMode;
int doublePrecision; int doublePrecision;
QByteArray buildIndent(int spaces);
QByteArray serialize( const QVariant &v, bool *ok, int indentLevel = 0); 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 ) { 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; 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 Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok, int indentLevel)
{ {
QByteArray str; QByteArray str;
const QVariant::Type type = v.type();
if ( ! v.isValid() ) { // invalid or null? if ( ! v.isValid() ) { // invalid or null?
str = "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(); const QVariantList list = v.toList();
QList<QByteArray> values; QList<QByteArray> values;
Q_FOREACH( const QVariant& var, list ) 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 ) { if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull ) {
QByteArray indent = buildIndent(indentLevel); 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) { else if (indentMode == QJson::IndentMinimum) {
QByteArray indent = buildIndent(indentLevel); 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) { else if (indentMode == QJson::IndentCompact) {
str = "[" + join( values, "," ) + "]"; str = '[' + join( values, "," ) + ']';
} }
else { else {
str = "[ " + join( values, ", " ) + " ]"; 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(); const QVariantMap vmap = v.toMap();
QMapIterator<QString, QVariant> it( vmap );
if (indentMode == QJson::IndentMinimum) { if (indentMode == QJson::IndentMinimum) {
QByteArray indent = buildIndent(indentLevel); QByteArray indent = buildIndent(indentLevel);
@ -135,18 +154,17 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
} }
QList<QByteArray> pairs; QList<QByteArray> pairs;
while ( it.hasNext() ) { for (QVariantMap::const_iterator it = vmap.begin(), end = vmap.end(); it != end; ++it) {
it.next();
indentLevel++; indentLevel++;
QByteArray serializedValue = serialize( it.value(), ok, indentLevel); QByteArray serializedValue = serialize( it.value(), ok, indentLevel);
indentLevel--; indentLevel--;
if ( !*ok ) { if ( !*ok ) {
break; break;
} }
QByteArray key = sanitizeString( it.key() ).toUtf8(); QByteArray key = escapeString( it.key() );
QByteArray value = serializedValue.trimmed(); QByteArray value = serializedValue.trimmed();
if (indentMode == QJson::IndentCompact) { if (indentMode == QJson::IndentCompact) {
pairs << key + ":" + value; pairs << key + ':' + value;
} else { } else {
pairs << key + " : " + value; pairs << key + " : " + value;
} }
@ -157,7 +175,7 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
str += join( pairs, ",\n" + indent); str += join( pairs, ",\n" + indent);
} }
else if (indentMode == QJson::IndentCompact) { else if (indentMode == QJson::IndentCompact) {
str += join( pairs, "," ); str += join( pairs, ',' );
} }
else { else {
str += join( pairs, ", " ); str += join( pairs, ", " );
@ -165,18 +183,17 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) { if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
QByteArray indent = buildIndent(indentLevel); QByteArray indent = buildIndent(indentLevel);
str += "\n" + indent + "}"; str += '\n' + indent + '}';
} }
else if (indentMode == QJson::IndentCompact) { else if (indentMode == QJson::IndentCompact) {
str += "}"; str += '}';
} }
else { else {
str += " }"; 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(); const QVariantHash vhash = v.toHash();
QHashIterator<QString, QVariant> it( vhash );
if (indentMode == QJson::IndentMinimum) { if (indentMode == QJson::IndentMinimum) {
QByteArray indent = buildIndent(indentLevel); QByteArray indent = buildIndent(indentLevel);
@ -195,18 +212,16 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
} }
QList<QByteArray> pairs; QList<QByteArray> pairs;
while ( it.hasNext() ) { for (QVariantHash::const_iterator it = vhash.begin(), end = vhash.end(); it != end; ++it) {
it.next();
QByteArray serializedValue = serialize( it.value(), ok, indentLevel + 1); QByteArray serializedValue = serialize( it.value(), ok, indentLevel + 1);
if ( !*ok ) { if ( !*ok ) {
break; break;
} }
QByteArray key = sanitizeString( it.key() ).toUtf8(); QByteArray key = escapeString( it.key() );
QByteArray value = serializedValue.trimmed(); QByteArray value = serializedValue.trimmed();
if (indentMode == QJson::IndentCompact) { if (indentMode == QJson::IndentCompact) {
pairs << key + ":" + value; pairs << key + ':' + value;
} else { } else {
pairs << key + " : " + value; pairs << key + " : " + value;
} }
@ -217,7 +232,7 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
str += join( pairs, ",\n" + indent); str += join( pairs, ",\n" + indent);
} }
else if (indentMode == QJson::IndentCompact) { else if (indentMode == QJson::IndentCompact) {
str += join( pairs, "," ); str += join( pairs, ',' );
} }
else { else {
str += join( pairs, ", " ); str += join( pairs, ", " );
@ -225,10 +240,10 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) { if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
QByteArray indent = buildIndent(indentLevel); QByteArray indent = buildIndent(indentLevel);
str += "\n" + indent + "}"; str += '\n' + indent + '}';
} }
else if (indentMode == QJson::IndentCompact) { else if (indentMode == QJson::IndentCompact) {
str += "}"; str += '}';
} }
else { else {
str += " }"; str += " }";
@ -248,9 +263,9 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
break; break;
} }
if (( v.type() == QVariant::String ) || ( v.type() == QVariant::ByteArray )) { // a string or a byte array? if (( type == QVariant::String ) || ( type == QVariant::ByteArray )) { // a string or a byte array?
str = sanitizeString( v.toString() ).toUtf8(); str += escapeString( v.toString() );
} else if (( v.type() == QVariant::Double) || ((QMetaType::Type)v.type() == QMetaType::Float)) { // a double or a float? } else if (( type == QVariant::Double) || ((QMetaType::Type)type == QMetaType::Float)) { // a double or a float?
const double value = v.toDouble(); const double value = v.toDouble();
#if defined _WIN32 && !defined(Q_OS_SYMBIAN) #if defined _WIN32 && !defined(Q_OS_SYMBIAN)
const bool special = _isnan(value) || !_finite(value); const bool special = _isnan(value) || !_finite(value);
@ -281,15 +296,15 @@ QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok
} }
} else { } else {
str = QByteArray::number( value , 'g', doublePrecision); str = QByteArray::number( value , 'g', doublePrecision);
if( ! str.contains( "." ) && ! str.contains( "e" ) ) { if( !str.contains( '.' ) && !str.contains( 'e' ) ) {
str += ".0"; str += ".0";
} }
} }
} else if ( v.type() == QVariant::Bool ) { // boolean value? } else if ( type == QVariant::Bool ) { // boolean value?
str += ( v.toBool() ? "true" : "false" ); 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>() ); 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>() ); str += QByteArray::number( v.value<quint32>() );
} else if ( v.canConvert<qlonglong>() ) { // any signed number? } else if ( v.canConvert<qlonglong>() ) { // any signed number?
str += QByteArray::number( v.value<qlonglong>() ); 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>() ); str += QByteArray::number( v.value<int>() );
} else if ( v.canConvert<QString>() ){ // can value be converted to string? } else if ( v.canConvert<QString>() ){ // can value be converted to string?
// this will catch QDate, QDateTime, QUrl, ... // this will catch QDate, QDateTime, QUrl, ...
str += sanitizeString( v.toString() ).toUtf8(); str += escapeString( v.toString() );
//TODO: catch other values like QImage, QRect, ... //TODO: catch other values like QImage, QRect, ...
} else { } else {
*ok = false; *ok = false;
@ -323,42 +338,52 @@ QByteArray Serializer::SerializerPrivate::buildIndent(int spaces)
spaces = 0; spaces = 0;
} }
for (int i = 0; i < spaces; i++ ) { for (int i = 0; i < spaces; i++ ) {
indent += " "; indent += ' ';
} }
return indent; return indent;
} }
QString Serializer::SerializerPrivate::sanitizeString( QString str ) QByteArray Serializer::SerializerPrivate::escapeString( const QString& str )
{ {
str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) ); QByteArray result;
result.reserve(str.size() + 2);
// escape unicode chars result.append('\"');
QString result; for (QString::const_iterator it = str.begin(), end = str.end(); it != end; ++it) {
const ushort* unicode = str.utf16(); ushort unicode = it->unicode();
unsigned int i = 0; switch ( unicode ) {
case '\"':
while ( unicode[ i ] ) { result.append("\\\"");
if ( unicode[ i ] < 128 ) { break;
result.append( QChar( unicode[ i ] ) ); case '\\':
} result.append("\\\\");
else { break;
QString hexCode = QString::number( unicode[ i ], 16 ).rightJustified( 4, case '\b':
QLatin1Char('0') ); result.append("\\b");
break;
result.append( QLatin1String ("\\u") ).append( hexCode ); 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);
}
} }
++i;
} }
str = result; result.append('\"');
return 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 );
} }
Serializer::Serializer() Serializer::Serializer()

Loading…
Cancel
Save