Anonymous | Login | Signup for a new account | 2024-04-19 06:36 UTC |
My View | View Issues | Change Log | Roadmap | Doomseeker Issue Support Ranking | Rules | My Account |
View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0003794 | Doomseeker | [All Projects] Cleanup | public | 2020-06-05 07:05 | 2021-08-16 19:10 | ||||
Reporter | WubTheCaptain | ||||||||
Assigned To | WubTheCaptain | ||||||||
Priority | low | Severity | trivial | Reproducibility | always | ||||
Status | closed | Resolution | won't fix | ||||||
Platform | OS | OS Version | |||||||
Product Version | 1.3.1 | ||||||||
Target Version | 1.3.2 | Fixed in Version | |||||||
Summary | 0003794: qt-json is older than aa0930a (stray #include <iostream>) | ||||||||
Description | A stray #include <iostream> in src/core/json.cpp triggered me today: Nothing in the file depends on standard library header <iostream>. Then I remembered that file is from Eeli Reilin's JSON library (qt-json). I then found out upstream had already fixed this issue (e84dce6), but the copy included in Doomseeker was older and didn't have this patch. | ||||||||
Attached Files | 0001-qt-json-Update-to-commit-aa0930a.patch [^] (31,483 bytes) 2020-06-05 07:06 [Show Content] [Hide Content]From 650a0676f494e95f9fd22d86e8bc8aaff4860043 Mon Sep 17 00:00:00 2001 From: Linda Lapinlampi <linda@lindalap.fi> Date: Fri, 5 Jun 2020 06:43:26 +0000 Subject: [PATCH 1/1] qt-json: Update to commit aa0930a A stray #include <iostream> in src/core/json.cpp triggered me today: Nothing in the file depends on standard library header <iostream>. Then I remembered that file is from Eeli Reilin's JSON library (qt-json). I then found out upstream had already fixed this issue (e84dce6), but the copy included in Doomseeker was older and didn't have this patch. The reason qt-json commit aa0930a is chosen is that it's the last 2-clause BSD-licensed version of the qt-json library, and compatible with Doomseeker's licensing. (qt-json commit ad14cd4 changed its license to GPLv3.) It also includes a fix for the before-mentioned "issue". Oh yeah, and we can use C++11 in Doomseeker / Wadseeker now. Standard library header <map> added range access in C++11. We were limited to the older version of this library earlier, because of C++98. qt-json aa0930a is from 2013, thus it should predate C++14. Any white-space changes (whitespace at end of lines) is as-is from the upstream's source file. So are the tabs at beginning of lines, near the end of json.cpp. I've not touched those. While here, upstream removed a class in commit c0297c2. This change is sensible, but not backwards compatible. Fortunately it's also easy to patch in our code. It may be better to use Git submodules (or something else) for qt-json dependency in the future. For now, patching our copy is a quick fix (without more intrusive changes to the build system). Fixes: #3794 --- src/core/json.cpp | 272 ++++++++++++++++--------- src/core/json.h | 272 ++++++++----------------- src/core/updater/updaterinfoparser.cpp | 2 +- src/core/versiondump.cpp | 2 +- 4 files changed, 260 insertions(+), 288 deletions(-) diff --git a/src/core/json.cpp b/src/core/json.cpp index 63cea459..4021d088 100644 --- a/src/core/json.cpp +++ b/src/core/json.cpp @@ -1,28 +1,28 @@ /* Copyright 2011 Eeli Reilin. All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, + * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation + * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing * official policies, either expressed or implied, of Eeli Reilin. */ @@ -31,51 +31,61 @@ */ #include "json.h" -#include <iostream> namespace QtJson { -static QString sanitizeString(QString str) +static QString sanitizeString(QString str); +static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep); +static QVariant parseValue(const QString &json, int &index, bool &success); +static QVariant parseObject(const QString &json, int &index, bool &success); +static QVariant parseArray(const QString &json, int &index, bool &success); +static QVariant parseString(const QString &json, int &index, bool &success); +static QVariant parseNumber(const QString &json, int &index); +static int lastIndexOfNumber(const QString &json, int index); +static void eatWhitespace(const QString &json, int &index); +static int lookAhead(const QString &json, int index); +static int nextToken(const QString &json, int &index); + +template<typename T> +QByteArray serializeMap(const T &map, bool &success) { - str.replace(QLatin1String("\\"), QLatin1String("\\\\")); - 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); -} + QByteArray str = "{ "; + QList<QByteArray> pairs; + for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { + QByteArray serializedValue = serialize(it.value()); -static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) -{ - QByteArray res; - Q_FOREACH(const QByteArray &i, list) + if(serializedValue.isNull()) { - if(!res.isEmpty()) - { - res += sep; - } - res += i; + success = false; + break; } - return res; + + pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; + } + + str += join(pairs, ", "); + str += " }"; + return str; } +/***** public *****/ + + /** * parse */ -QVariant Json::parse(const QString &json) +QVariant parse(const QString &json) { bool success = true; - return Json::parse(json, success); + return parse(json, success); } /** * parse */ -QVariant Json::parse(const QString &json, bool &success) +QVariant parse(const QString &json, bool &success) { success = true; @@ -87,7 +97,7 @@ QVariant Json::parse(const QString &json, bool &success) int index = 0; //Parse the first value - QVariant value = Json::parseValue(data, index, success); + QVariant value = parseValue(data, index, success); //Return the parsed value return value; @@ -99,13 +109,13 @@ QVariant Json::parse(const QString &json, bool &success) } } -QByteArray Json::serialize(const QVariant &data) +QByteArray serialize(const QVariant &data) { bool success = true; - return Json::serialize(data, success); + return serialize(data, success); } -QByteArray Json::serialize(const QVariant &data, bool &success) +QByteArray serialize(const QVariant &data, bool &success) { QByteArray str; success = true; @@ -131,25 +141,13 @@ QByteArray Json::serialize(const QVariant &data, bool &success) str = "[ " + join( values, ", " ) + " ]"; } + else if(data.type() == QVariant::Hash) // variant is a hash? + { + str = serializeMap<>(data.toHash(), success); + } else if(data.type() == QVariant::Map) // variant is a map? { - const QVariantMap vmap = data.toMap(); - QMapIterator<QString, QVariant> it( vmap ); - str = "{ "; - QList<QByteArray> pairs; - while(it.hasNext()) - { - it.next(); - QByteArray serializedValue = serialize(it.value()); - if(serializedValue.isNull()) - { - success = false; - break; - } - pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; - } - str += join(pairs, ", "); - str += " }"; + str = serializeMap<>(data.toMap(), success); } else if((data.type() == QVariant::String) || (data.type() == QVariant::ByteArray)) // a string or a byte array? { @@ -157,10 +155,15 @@ QByteArray Json::serialize(const QVariant &data, bool &success) } else if(data.type() == QVariant::Double) // double? { - str = QByteArray::number(data.toDouble(), 'g', 20); - if(!str.contains(".") && ! str.contains("e")) - { - str += ".0"; + double value = data.toDouble(); + if ((value - value) == 0.0) { + str = QByteArray::number(value, 'g', 20); + if(!str.contains(".") && ! str.contains("e")) + { + str += ".0"; + } + } else { + success = false; } } else if (data.type() == QVariant::Bool) // boolean value? @@ -175,7 +178,7 @@ QByteArray Json::serialize(const QVariant &data, bool &success) { str = QByteArray::number(data.value<qlonglong>()); } - else if (data.canConvert<long>()) + else if (data.canConvert<long>()) //TODO: this code is never executed { str = QString::number(data.value<long>()).toUtf8(); } @@ -198,31 +201,89 @@ QByteArray Json::serialize(const QVariant &data, bool &success) } } +QString serializeStr(const QVariant &data) +{ + return QString::fromUtf8(serialize(data)); +} + +QString serializeStr(const QVariant &data, bool &success) +{ + return QString::fromUtf8(serialize(data, success)); +} + +/***** private *****/ + + +/** + * \enum JsonToken + */ +enum JsonToken +{ + JsonTokenNone = 0, + JsonTokenCurlyOpen = 1, + JsonTokenCurlyClose = 2, + JsonTokenSquaredOpen = 3, + JsonTokenSquaredClose = 4, + JsonTokenColon = 5, + JsonTokenComma = 6, + JsonTokenString = 7, + JsonTokenNumber = 8, + JsonTokenTrue = 9, + JsonTokenFalse = 10, + JsonTokenNull = 11 +}; + +static QString sanitizeString(QString str) +{ + str.replace(QLatin1String("\\"), QLatin1String("\\\\")); + 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); +} + +static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) +{ + QByteArray res; + Q_FOREACH(const QByteArray &i, list) + { + if(!res.isEmpty()) + { + res += sep; + } + res += i; + } + return res; +} + /** * parseValue */ -QVariant Json::parseValue(const QString &json, int &index, bool &success) +static QVariant parseValue(const QString &json, int &index, bool &success) { //Determine what kind of data we should parse by //checking out the upcoming token - switch(Json::lookAhead(json, index)) + switch(lookAhead(json, index)) { case JsonTokenString: - return Json::parseString(json, index, success); + return parseString(json, index, success); case JsonTokenNumber: - return Json::parseNumber(json, index); + return parseNumber(json, index); case JsonTokenCurlyOpen: - return Json::parseObject(json, index, success); + return parseObject(json, index, success); case JsonTokenSquaredOpen: - return Json::parseArray(json, index, success); + return parseArray(json, index, success); case JsonTokenTrue: - Json::nextToken(json, index); + nextToken(json, index); return QVariant(true); case JsonTokenFalse: - Json::nextToken(json, index); + nextToken(json, index); return QVariant(false); case JsonTokenNull: - Json::nextToken(json, index); + nextToken(json, index); return QVariant(); case JsonTokenNone: break; @@ -236,20 +297,20 @@ QVariant Json::parseValue(const QString &json, int &index, bool &success) /** * parseObject */ -QVariant Json::parseObject(const QString &json, int &index, bool &success) +static QVariant parseObject(const QString &json, int &index, bool &success) { QVariantMap map; int token; //Get rid of the whitespace and increment index - Json::nextToken(json, index); + nextToken(json, index); //Loop through all of the key/value pairs of the object bool done = false; while(!done) { //Get the upcoming token - token = Json::lookAhead(json, index); + token = lookAhead(json, index); if(token == JsonTokenNone) { @@ -258,17 +319,17 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) } else if(token == JsonTokenComma) { - Json::nextToken(json, index); + nextToken(json, index); } else if(token == JsonTokenCurlyClose) { - Json::nextToken(json, index); + nextToken(json, index); return map; } else { //Parse the key/value pair's name - QString name = Json::parseString(json, index, success).toString(); + QString name = parseString(json, index, success).toString(); if(!success) { @@ -276,7 +337,7 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) } //Get the next token - token = Json::nextToken(json, index); + token = nextToken(json, index); //If the next token is not a colon, flag the failure //return an empty QVariant @@ -287,7 +348,7 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) } //Parse the key/value pair's value - QVariant value = Json::parseValue(json, index, success); + QVariant value = parseValue(json, index, success); if(!success) { @@ -306,16 +367,16 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) /** * parseArray */ -QVariant Json::parseArray(const QString &json, int &index, bool &success) +static QVariant parseArray(const QString &json, int &index, bool &success) { QVariantList list; - Json::nextToken(json, index); + nextToken(json, index); bool done = false; while(!done) { - int token = Json::lookAhead(json, index); + int token = lookAhead(json, index); if(token == JsonTokenNone) { @@ -324,16 +385,16 @@ QVariant Json::parseArray(const QString &json, int &index, bool &success) } else if(token == JsonTokenComma) { - Json::nextToken(json, index); + nextToken(json, index); } else if(token == JsonTokenSquaredClose) { - Json::nextToken(json, index); + nextToken(json, index); break; } else { - QVariant value = Json::parseValue(json, index, success); + QVariant value = parseValue(json, index, success); if(!success) { @@ -350,12 +411,12 @@ QVariant Json::parseArray(const QString &json, int &index, bool &success) /** * parseString */ -QVariant Json::parseString(const QString &json, int &index, bool &success) +static QVariant parseString(const QString &json, int &index, bool &success) { QString s; QChar c; - Json::eatWhitespace(json, index); + eatWhitespace(json, index); c = json[index++]; @@ -447,39 +508,50 @@ QVariant Json::parseString(const QString &json, int &index, bool &success) return QVariant(); } - s = QString::fromUtf8(s.toUtf8()); - return QVariant(s); } /** * parseNumber */ -QVariant Json::parseNumber(const QString &json, int &index) +static QVariant parseNumber(const QString &json, int &index) { - Json::eatWhitespace(json, index); + eatWhitespace(json, index); - int lastIndex = Json::lastIndexOfNumber(json, index); + int lastIndex = lastIndexOfNumber(json, index); int charLength = (lastIndex - index) + 1; QString numberStr; numberStr = json.mid(index, charLength); index = lastIndex + 1; + bool ok; if (numberStr.contains('.')) { return QVariant(numberStr.toDouble(NULL)); } else if (numberStr.startsWith('-')) { - return QVariant(numberStr.toLongLong(NULL)); + int i = numberStr.toInt(&ok); + if(!ok) + { + qlonglong ll = numberStr.toLongLong(&ok); + return ok ? ll : QVariant(numberStr); + } + return i; } else { - return QVariant(numberStr.toULongLong(NULL)); + uint u = numberStr.toUInt(&ok); + if(!ok) + { + qulonglong ull = numberStr.toULongLong(&ok); + return ok ? ull : QVariant(numberStr); + } + return u; } } /** * lastIndexOfNumber */ -int Json::lastIndexOfNumber(const QString &json, int index) +static int lastIndexOfNumber(const QString &json, int index) { int lastIndex; @@ -497,7 +569,7 @@ int Json::lastIndexOfNumber(const QString &json, int index) /** * eatWhitespace */ -void Json::eatWhitespace(const QString &json, int &index) +static void eatWhitespace(const QString &json, int &index) { for(; index < json.size(); index++) { @@ -511,18 +583,18 @@ void Json::eatWhitespace(const QString &json, int &index) /** * lookAhead */ -int Json::lookAhead(const QString &json, int index) +static int lookAhead(const QString &json, int index) { int saveIndex = index; - return Json::nextToken(json, saveIndex); + return nextToken(json, saveIndex); } /** * nextToken */ -int Json::nextToken(const QString &json, int &index) +static int nextToken(const QString &json, int &index) { - Json::eatWhitespace(json, index); + eatWhitespace(json, index); if(index == json.size()) { diff --git a/src/core/json.h b/src/core/json.h index 090e6a84..4cae52c6 100644 --- a/src/core/json.h +++ b/src/core/json.h @@ -1,34 +1,34 @@ /* Copyright 2011 Eeli Reilin. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -* EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation -* are those of the authors and should not be interpreted as representing -* official policies, either expressed or implied, of Eeli Reilin. -*/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of Eeli Reilin. + */ /** -* \file json.h -*/ + * \file json.h + */ #ifndef JSON_H #define JSON_H @@ -36,168 +36,68 @@ #include <QVariant> #include <QString> -namespace QtJson -{ - -/** -* \enum JsonToken -*/ -enum JsonToken -{ - JsonTokenNone = 0, - JsonTokenCurlyOpen = 1, - JsonTokenCurlyClose = 2, - JsonTokenSquaredOpen = 3, - JsonTokenSquaredClose = 4, - JsonTokenColon = 5, - JsonTokenComma = 6, - JsonTokenString = 7, - JsonTokenNumber = 8, - JsonTokenTrue = 9, - JsonTokenFalse = 10, - JsonTokenNull = 11 -}; /** -* \class Json -* \brief A JSON data parser -* -* Json parses a JSON data into a QVariant hierarchy. -*/ -class Json + * \namespace QtJson + * \brief A JSON data parser + * + * Json parses a JSON data into a QVariant hierarchy. + */ +namespace QtJson { - public: - /** -* Parse a JSON string -* -* \param json The JSON data -*/ - static QVariant parse(const QString &json); - - /** -* Parse a JSON string -* -* \param json The JSON data -* \param success The success of the parsing -*/ - static QVariant parse(const QString &json, bool &success); - - /** -* This method generates a textual JSON representation -* -* \param data The JSON data generated by the parser. -* \param success The success of the serialization -*/ - static QByteArray serialize(const QVariant &data); - - /** -* This method generates a textual JSON representation -* -* \param data The JSON data generated by the parser. -* \param success The success of the serialization -* -* \return QByteArray Textual JSON representation -*/ - static QByteArray serialize(const QVariant &data, bool &success); - - private: - /** -* Parses a value starting from index -* -* \param json The JSON data -* \param index The start index -* \param success The success of the parse process -* -* \return QVariant The parsed value -*/ - static QVariant parseValue(const QString &json, int &index, - bool &success); - - /** -* Parses an object starting from index -* -* \param json The JSON data -* \param index The start index -* \param success The success of the object parse -* -* \return QVariant The parsed object map -*/ - static QVariant parseObject(const QString &json, int &index, - bool &success); - - /** -* Parses an array starting from index -* -* \param json The JSON data -* \param index The starting index -* \param success The success of the array parse -* -* \return QVariant The parsed variant array -*/ - static QVariant parseArray(const QString &json, int &index, - bool &success); - - /** -* Parses a string starting from index -* -* \param json The JSON data -* \param index The starting index -* \param success The success of the string parse -* -* \return QVariant The parsed string -*/ - static QVariant parseString(const QString &json, int &index, - bool &success); - - /** -* Parses a number starting from index -* -* \param json The JSON data -* \param index The starting index -* -* \return QVariant The parsed number -*/ - static QVariant parseNumber(const QString &json, int &index); - - /** -* Get the last index of a number starting from index -* -* \param json The JSON data -* \param index The starting index -* -* \return The last index of the number -*/ - static int lastIndexOfNumber(const QString &json, int index); - - /** -* Skip unwanted whitespace symbols starting from index -* -* \param json The JSON data -* \param index The start index -*/ - static void eatWhitespace(const QString &json, int &index); - - /** -* Check what token lies ahead -* -* \param json The JSON data -* \param index The starting index -* -* \return int The upcoming token -*/ - static int lookAhead(const QString &json, int index); - - /** -* Get the next JSON token -* -* \param json The JSON data -* \param index The starting index -* -* \return int The next JSON token -*/ - static int nextToken(const QString &json, int &index); -}; + /** + * Parse a JSON string + * + * \param json The JSON data + */ + QVariant parse(const QString &json); + + /** + * Parse a JSON string + * + * \param json The JSON data + * \param success The success of the parsing + */ + QVariant parse(const QString &json, bool &success); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QByteArray Textual JSON representation in UTF-8 + */ + QByteArray serialize(const QVariant &data); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QByteArray Textual JSON representation in UTF-8 + */ + QByteArray serialize(const QVariant &data, bool &success); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QString Textual JSON representation + */ + QString serializeStr(const QVariant &data); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QString Textual JSON representation + */ + QString serializeStr(const QVariant &data, bool &success); } //end namespace diff --git a/src/core/updater/updaterinfoparser.cpp b/src/core/updater/updaterinfoparser.cpp index ed607c5e..559a863d 100644 --- a/src/core/updater/updaterinfoparser.cpp +++ b/src/core/updater/updaterinfoparser.cpp @@ -56,7 +56,7 @@ const QList<UpdatePackage> &UpdaterInfoParser::packages() const int UpdaterInfoParser::parse(const QByteArray &json) { d->packages.clear(); - QVariant var = QtJson::Json::parse(json); + QVariant var = QtJson::parse(json); if (var.isValid()) { QVariantMap metaData = var.toMap(); diff --git a/src/core/versiondump.cpp b/src/core/versiondump.cpp index 6238b839..40f501f0 100644 --- a/src/core/versiondump.cpp +++ b/src/core/versiondump.cpp @@ -79,6 +79,6 @@ void VersionDump::dumpJsonToIO(QIODevice &io) root[keyword] = Module(name, QString::number(plugin->info()->data()->version)).toVariantMap(); } - io.write(QtJson::Json::serialize(root)); + io.write(QtJson::serialize(root)); io.write("\n"); } -- 2.27.0 0002-Update-qt-json-in-wadseeker-too.patch [^] (31,390 bytes) 2020-06-05 07:22 [Show Content] [Hide Content] From 2e8d8ef5a9b8597eb7438a7511a2ab07e318c99d Mon Sep 17 00:00:00 2001 From: Linda Lapinlampi <linda@lindalap.fi> Date: Fri, 5 Jun 2020 07:11:42 +0000 Subject: [PATCH 2/2] Update qt-json in wadseeker too Bleh, we have two copies of Eeli Reilin's JSON library in the source tree. My former commit moments ago updated the copy of qt-json in Doomseeker (src/core/) only. I brought this up in 2017 in issue #3310, but there was no consensus to deduplicate these files. So patch (update) the qt-json dependency under src/wadseeker too to commit aa0930a, to address my personal issue of <iostream> appearing unnecessarily in grep for source text search. --- .../protocols/idgames/idgamesreply.cpp | 4 +- src/wadseeker/protocols/json.cpp | 274 +++++++++++------- src/wadseeker/protocols/json.h | 272 ++++++----------- .../protocols/wadarchive/wadarchiveclient.cpp | 4 +- 4 files changed, 263 insertions(+), 291 deletions(-) diff --git a/src/wadseeker/protocols/idgames/idgamesreply.cpp b/src/wadseeker/protocols/idgames/idgamesreply.cpp index 5fdf4414..13d2a3ea 100644 --- a/src/wadseeker/protocols/idgames/idgamesreply.cpp +++ b/src/wadseeker/protocols/idgames/idgamesreply.cpp @@ -75,9 +75,9 @@ void IdgamesReply::onNetworkFinished() QString json = d->reply->readAll(); #ifndef NDEBUG qDebug() << "idgames onNetworkFinished()" << json; - qDebug() << "idgames onNetworkFinished() parsed" << QtJson::Json::parse(json); + qDebug() << "idgames onNetworkFinished() parsed" << QtJson::parse(json); #endif - finish(IdgamesResult(QtJson::Json::parse(json))); + finish(IdgamesResult(QtJson::parse(json))); } } else diff --git a/src/wadseeker/protocols/json.cpp b/src/wadseeker/protocols/json.cpp index 2f7acb87..4021d088 100644 --- a/src/wadseeker/protocols/json.cpp +++ b/src/wadseeker/protocols/json.cpp @@ -1,28 +1,28 @@ /* Copyright 2011 Eeli Reilin. All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, + * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation + * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing * official policies, either expressed or implied, of Eeli Reilin. */ @@ -31,51 +31,61 @@ */ #include "json.h" -#include <iostream> namespace QtJson { -static QString sanitizeString(QString str) +static QString sanitizeString(QString str); +static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep); +static QVariant parseValue(const QString &json, int &index, bool &success); +static QVariant parseObject(const QString &json, int &index, bool &success); +static QVariant parseArray(const QString &json, int &index, bool &success); +static QVariant parseString(const QString &json, int &index, bool &success); +static QVariant parseNumber(const QString &json, int &index); +static int lastIndexOfNumber(const QString &json, int index); +static void eatWhitespace(const QString &json, int &index); +static int lookAhead(const QString &json, int index); +static int nextToken(const QString &json, int &index); + +template<typename T> +QByteArray serializeMap(const T &map, bool &success) { - str.replace(QLatin1String("\\"), QLatin1String("\\\\")); - 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); -} + QByteArray str = "{ "; + QList<QByteArray> pairs; + for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { + QByteArray serializedValue = serialize(it.value()); -static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) -{ - QByteArray res; - Q_FOREACH(const QByteArray &i, list) + if(serializedValue.isNull()) { - if(!res.isEmpty()) - { - res += sep; - } - res += i; + success = false; + break; } - return res; + + pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; + } + + str += join(pairs, ", "); + str += " }"; + return str; } +/***** public *****/ + + /** * parse */ -QVariant Json::parse(const QString &json) +QVariant parse(const QString &json) { bool success = true; - return Json::parse(json, success); + return parse(json, success); } /** * parse */ -QVariant Json::parse(const QString &json, bool &success) +QVariant parse(const QString &json, bool &success) { success = true; @@ -87,7 +97,7 @@ QVariant Json::parse(const QString &json, bool &success) int index = 0; //Parse the first value - QVariant value = Json::parseValue(data, index, success); + QVariant value = parseValue(data, index, success); //Return the parsed value return value; @@ -99,13 +109,13 @@ QVariant Json::parse(const QString &json, bool &success) } } -QByteArray Json::serialize(const QVariant &data) +QByteArray serialize(const QVariant &data) { bool success = true; - return Json::serialize(data, success); + return serialize(data, success); } -QByteArray Json::serialize(const QVariant &data, bool &success) +QByteArray serialize(const QVariant &data, bool &success) { QByteArray str; success = true; @@ -131,25 +141,13 @@ QByteArray Json::serialize(const QVariant &data, bool &success) str = "[ " + join( values, ", " ) + " ]"; } + else if(data.type() == QVariant::Hash) // variant is a hash? + { + str = serializeMap<>(data.toHash(), success); + } else if(data.type() == QVariant::Map) // variant is a map? { - const QVariantMap vmap = data.toMap(); - QMapIterator<QString, QVariant> it( vmap ); - str = "{ "; - QList<QByteArray> pairs; - while(it.hasNext()) - { - it.next(); - QByteArray serializedValue = serialize(it.value()); - if(serializedValue.isNull()) - { - success = false; - break; - } - pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; - } - str += join(pairs, ", "); - str += " }"; + str = serializeMap<>(data.toMap(), success); } else if((data.type() == QVariant::String) || (data.type() == QVariant::ByteArray)) // a string or a byte array? { @@ -157,10 +155,15 @@ QByteArray Json::serialize(const QVariant &data, bool &success) } else if(data.type() == QVariant::Double) // double? { - str = QByteArray::number(data.toDouble(), 'g', 20); - if(!str.contains(".") && ! str.contains("e")) - { - str += ".0"; + double value = data.toDouble(); + if ((value - value) == 0.0) { + str = QByteArray::number(value, 'g', 20); + if(!str.contains(".") && ! str.contains("e")) + { + str += ".0"; + } + } else { + success = false; } } else if (data.type() == QVariant::Bool) // boolean value? @@ -175,7 +178,7 @@ QByteArray Json::serialize(const QVariant &data, bool &success) { str = QByteArray::number(data.value<qlonglong>()); } - else if (data.canConvert<long>()) + else if (data.canConvert<long>()) //TODO: this code is never executed { str = QString::number(data.value<long>()).toUtf8(); } @@ -198,31 +201,89 @@ QByteArray Json::serialize(const QVariant &data, bool &success) } } +QString serializeStr(const QVariant &data) +{ + return QString::fromUtf8(serialize(data)); +} + +QString serializeStr(const QVariant &data, bool &success) +{ + return QString::fromUtf8(serialize(data, success)); +} + +/***** private *****/ + + +/** + * \enum JsonToken + */ +enum JsonToken +{ + JsonTokenNone = 0, + JsonTokenCurlyOpen = 1, + JsonTokenCurlyClose = 2, + JsonTokenSquaredOpen = 3, + JsonTokenSquaredClose = 4, + JsonTokenColon = 5, + JsonTokenComma = 6, + JsonTokenString = 7, + JsonTokenNumber = 8, + JsonTokenTrue = 9, + JsonTokenFalse = 10, + JsonTokenNull = 11 +}; + +static QString sanitizeString(QString str) +{ + str.replace(QLatin1String("\\"), QLatin1String("\\\\")); + 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); +} + +static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) +{ + QByteArray res; + Q_FOREACH(const QByteArray &i, list) + { + if(!res.isEmpty()) + { + res += sep; + } + res += i; + } + return res; +} + /** * parseValue */ -QVariant Json::parseValue(const QString &json, int &index, bool &success) +static QVariant parseValue(const QString &json, int &index, bool &success) { //Determine what kind of data we should parse by //checking out the upcoming token - switch(Json::lookAhead(json, index)) + switch(lookAhead(json, index)) { case JsonTokenString: - return Json::parseString(json, index, success); + return parseString(json, index, success); case JsonTokenNumber: - return Json::parseNumber(json, index); + return parseNumber(json, index); case JsonTokenCurlyOpen: - return Json::parseObject(json, index, success); + return parseObject(json, index, success); case JsonTokenSquaredOpen: - return Json::parseArray(json, index, success); + return parseArray(json, index, success); case JsonTokenTrue: - Json::nextToken(json, index); + nextToken(json, index); return QVariant(true); case JsonTokenFalse: - Json::nextToken(json, index); + nextToken(json, index); return QVariant(false); case JsonTokenNull: - Json::nextToken(json, index); + nextToken(json, index); return QVariant(); case JsonTokenNone: break; @@ -236,20 +297,20 @@ QVariant Json::parseValue(const QString &json, int &index, bool &success) /** * parseObject */ -QVariant Json::parseObject(const QString &json, int &index, bool &success) +static QVariant parseObject(const QString &json, int &index, bool &success) { QVariantMap map; int token; //Get rid of the whitespace and increment index - Json::nextToken(json, index); + nextToken(json, index); //Loop through all of the key/value pairs of the object bool done = false; while(!done) { //Get the upcoming token - token = Json::lookAhead(json, index); + token = lookAhead(json, index); if(token == JsonTokenNone) { @@ -258,17 +319,17 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) } else if(token == JsonTokenComma) { - Json::nextToken(json, index); + nextToken(json, index); } else if(token == JsonTokenCurlyClose) { - Json::nextToken(json, index); + nextToken(json, index); return map; } else { //Parse the key/value pair's name - QString name = Json::parseString(json, index, success).toString(); + QString name = parseString(json, index, success).toString(); if(!success) { @@ -276,7 +337,7 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) } //Get the next token - token = Json::nextToken(json, index); + token = nextToken(json, index); //If the next token is not a colon, flag the failure //return an empty QVariant @@ -287,7 +348,7 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) } //Parse the key/value pair's value - QVariant value = Json::parseValue(json, index, success); + QVariant value = parseValue(json, index, success); if(!success) { @@ -306,16 +367,16 @@ QVariant Json::parseObject(const QString &json, int &index, bool &success) /** * parseArray */ -QVariant Json::parseArray(const QString &json, int &index, bool &success) +static QVariant parseArray(const QString &json, int &index, bool &success) { QVariantList list; - Json::nextToken(json, index); + nextToken(json, index); bool done = false; while(!done) { - int token = Json::lookAhead(json, index); + int token = lookAhead(json, index); if(token == JsonTokenNone) { @@ -324,16 +385,16 @@ QVariant Json::parseArray(const QString &json, int &index, bool &success) } else if(token == JsonTokenComma) { - Json::nextToken(json, index); + nextToken(json, index); } else if(token == JsonTokenSquaredClose) { - Json::nextToken(json, index); + nextToken(json, index); break; } else { - QVariant value = Json::parseValue(json, index, success); + QVariant value = parseValue(json, index, success); if(!success) { @@ -350,12 +411,12 @@ QVariant Json::parseArray(const QString &json, int &index, bool &success) /** * parseString */ -QVariant Json::parseString(const QString &json, int &index, bool &success) +static QVariant parseString(const QString &json, int &index, bool &success) { QString s; QChar c; - Json::eatWhitespace(json, index); + eatWhitespace(json, index); c = json[index++]; @@ -447,39 +508,50 @@ QVariant Json::parseString(const QString &json, int &index, bool &success) return QVariant(); } - s = QString::fromUtf8(s.toUtf8()); - return QVariant(s); } /** * parseNumber */ -QVariant Json::parseNumber(const QString &json, int &index) +static QVariant parseNumber(const QString &json, int &index) { - Json::eatWhitespace(json, index); + eatWhitespace(json, index); - int lastIndex = Json::lastIndexOfNumber(json, index); + int lastIndex = lastIndexOfNumber(json, index); int charLength = (lastIndex - index) + 1; QString numberStr; numberStr = json.mid(index, charLength); index = lastIndex + 1; + bool ok; if (numberStr.contains('.')) { - return QVariant(numberStr.toDouble(nullptr)); + return QVariant(numberStr.toDouble(NULL)); } else if (numberStr.startsWith('-')) { - return QVariant(numberStr.toLongLong(nullptr)); + int i = numberStr.toInt(&ok); + if(!ok) + { + qlonglong ll = numberStr.toLongLong(&ok); + return ok ? ll : QVariant(numberStr); + } + return i; } else { - return QVariant(numberStr.toULongLong(nullptr)); + uint u = numberStr.toUInt(&ok); + if(!ok) + { + qulonglong ull = numberStr.toULongLong(&ok); + return ok ? ull : QVariant(numberStr); + } + return u; } } /** * lastIndexOfNumber */ -int Json::lastIndexOfNumber(const QString &json, int index) +static int lastIndexOfNumber(const QString &json, int index) { int lastIndex; @@ -497,7 +569,7 @@ int Json::lastIndexOfNumber(const QString &json, int index) /** * eatWhitespace */ -void Json::eatWhitespace(const QString &json, int &index) +static void eatWhitespace(const QString &json, int &index) { for(; index < json.size(); index++) { @@ -511,18 +583,18 @@ void Json::eatWhitespace(const QString &json, int &index) /** * lookAhead */ -int Json::lookAhead(const QString &json, int index) +static int lookAhead(const QString &json, int index) { int saveIndex = index; - return Json::nextToken(json, saveIndex); + return nextToken(json, saveIndex); } /** * nextToken */ -int Json::nextToken(const QString &json, int &index) +static int nextToken(const QString &json, int &index) { - Json::eatWhitespace(json, index); + eatWhitespace(json, index); if(index == json.size()) { diff --git a/src/wadseeker/protocols/json.h b/src/wadseeker/protocols/json.h index 090e6a84..4cae52c6 100644 --- a/src/wadseeker/protocols/json.h +++ b/src/wadseeker/protocols/json.h @@ -1,34 +1,34 @@ /* Copyright 2011 Eeli Reilin. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -* EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation -* are those of the authors and should not be interpreted as representing -* official policies, either expressed or implied, of Eeli Reilin. -*/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL EELI REILIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of Eeli Reilin. + */ /** -* \file json.h -*/ + * \file json.h + */ #ifndef JSON_H #define JSON_H @@ -36,168 +36,68 @@ #include <QVariant> #include <QString> -namespace QtJson -{ - -/** -* \enum JsonToken -*/ -enum JsonToken -{ - JsonTokenNone = 0, - JsonTokenCurlyOpen = 1, - JsonTokenCurlyClose = 2, - JsonTokenSquaredOpen = 3, - JsonTokenSquaredClose = 4, - JsonTokenColon = 5, - JsonTokenComma = 6, - JsonTokenString = 7, - JsonTokenNumber = 8, - JsonTokenTrue = 9, - JsonTokenFalse = 10, - JsonTokenNull = 11 -}; /** -* \class Json -* \brief A JSON data parser -* -* Json parses a JSON data into a QVariant hierarchy. -*/ -class Json + * \namespace QtJson + * \brief A JSON data parser + * + * Json parses a JSON data into a QVariant hierarchy. + */ +namespace QtJson { - public: - /** -* Parse a JSON string -* -* \param json The JSON data -*/ - static QVariant parse(const QString &json); - - /** -* Parse a JSON string -* -* \param json The JSON data -* \param success The success of the parsing -*/ - static QVariant parse(const QString &json, bool &success); - - /** -* This method generates a textual JSON representation -* -* \param data The JSON data generated by the parser. -* \param success The success of the serialization -*/ - static QByteArray serialize(const QVariant &data); - - /** -* This method generates a textual JSON representation -* -* \param data The JSON data generated by the parser. -* \param success The success of the serialization -* -* \return QByteArray Textual JSON representation -*/ - static QByteArray serialize(const QVariant &data, bool &success); - - private: - /** -* Parses a value starting from index -* -* \param json The JSON data -* \param index The start index -* \param success The success of the parse process -* -* \return QVariant The parsed value -*/ - static QVariant parseValue(const QString &json, int &index, - bool &success); - - /** -* Parses an object starting from index -* -* \param json The JSON data -* \param index The start index -* \param success The success of the object parse -* -* \return QVariant The parsed object map -*/ - static QVariant parseObject(const QString &json, int &index, - bool &success); - - /** -* Parses an array starting from index -* -* \param json The JSON data -* \param index The starting index -* \param success The success of the array parse -* -* \return QVariant The parsed variant array -*/ - static QVariant parseArray(const QString &json, int &index, - bool &success); - - /** -* Parses a string starting from index -* -* \param json The JSON data -* \param index The starting index -* \param success The success of the string parse -* -* \return QVariant The parsed string -*/ - static QVariant parseString(const QString &json, int &index, - bool &success); - - /** -* Parses a number starting from index -* -* \param json The JSON data -* \param index The starting index -* -* \return QVariant The parsed number -*/ - static QVariant parseNumber(const QString &json, int &index); - - /** -* Get the last index of a number starting from index -* -* \param json The JSON data -* \param index The starting index -* -* \return The last index of the number -*/ - static int lastIndexOfNumber(const QString &json, int index); - - /** -* Skip unwanted whitespace symbols starting from index -* -* \param json The JSON data -* \param index The start index -*/ - static void eatWhitespace(const QString &json, int &index); - - /** -* Check what token lies ahead -* -* \param json The JSON data -* \param index The starting index -* -* \return int The upcoming token -*/ - static int lookAhead(const QString &json, int index); - - /** -* Get the next JSON token -* -* \param json The JSON data -* \param index The starting index -* -* \return int The next JSON token -*/ - static int nextToken(const QString &json, int &index); -}; + /** + * Parse a JSON string + * + * \param json The JSON data + */ + QVariant parse(const QString &json); + + /** + * Parse a JSON string + * + * \param json The JSON data + * \param success The success of the parsing + */ + QVariant parse(const QString &json, bool &success); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QByteArray Textual JSON representation in UTF-8 + */ + QByteArray serialize(const QVariant &data); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QByteArray Textual JSON representation in UTF-8 + */ + QByteArray serialize(const QVariant &data, bool &success); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QString Textual JSON representation + */ + QString serializeStr(const QVariant &data); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QString Textual JSON representation + */ + QString serializeStr(const QVariant &data, bool &success); } //end namespace diff --git a/src/wadseeker/protocols/wadarchive/wadarchiveclient.cpp b/src/wadseeker/protocols/wadarchive/wadarchiveclient.cpp index 60801e1a..4d5ff644 100644 --- a/src/wadseeker/protocols/wadarchive/wadarchiveclient.cpp +++ b/src/wadseeker/protocols/wadarchive/wadarchiveclient.cpp @@ -172,8 +172,8 @@ void WadArchiveClient::onQueryFinished() if (d->replyName->isFinished() && d->replyChecksum->isFinished()) { emit message(tr("Wad Archive query finished."), WadseekerLib::Notice); - QVariantList elementsName = QtJson::Json::parse(d->replyName->readAll()).toList(); - QVariantMap elementsChecksum = QtJson::Json::parse(d->replyChecksum->readAll()).toMap(); + QVariantList elementsName = QtJson::parse(d->replyName->readAll()).toList(); + QVariantMap elementsChecksum = QtJson::parse(d->replyChecksum->readAll()).toMap(); if (elementsName.size() > 0) { parseWadArchiveStructure(elementsName[0].toMap(), elementsChecksum); -- 2.27.0 0003-Fix-QtJson-parse-class-reference-in-freedoominfopars.patch [^] (1,069 bytes) 2020-06-05 08:34 [Show Content] [Hide Content] From 527a7a8fa7eed25b0f1335a6c2e01dc298340a7b Mon Sep 17 00:00:00 2001 From: Linda Lapinlampi <linda@lindalap.fi> Date: Fri, 5 Jun 2020 08:31:27 +0000 Subject: [PATCH 3/3] Fix QtJson::parse class reference in freedoominfoparser I was too distracted by everything falling apart while updating qt-json to aa0930a to miss this compile error. Whoops. FTBFS, fixed. See: #3794 --- src/wadseeker/protocols/freedoom/freedoominfoparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wadseeker/protocols/freedoom/freedoominfoparser.cpp b/src/wadseeker/protocols/freedoom/freedoominfoparser.cpp index d0c582b8..def89628 100644 --- a/src/wadseeker/protocols/freedoom/freedoominfoparser.cpp +++ b/src/wadseeker/protocols/freedoom/freedoominfoparser.cpp @@ -38,7 +38,7 @@ public: void readRoot() { QString str = QString::fromUtf8(contents.data(), contents.size()); - root = QtJson::Json::parse(str).toMap(); + root = QtJson::parse(str).toMap(); } void parseAndAppendModFile(const QString &filename, const QVariantMap &var) -- 2.27.0 | ||||||||
Relationships | |||||||||||
|
Notes | |
(0021351) WubTheCaptain (reporter) 2020-06-05 07:17 |
I got bitten by issue 0003310 after sharing the first patch file, so two patch files are attached. |
(0021352) WubTheCaptain (reporter) 2020-06-05 07:25 |
(re-attached 0002-Update-qt-json-in-wadseeker-too.patch, because I initially forgot to update Wadseeker's references to the class and that failed to build from source.) |
(0021353) WubTheCaptain (reporter) 2020-06-05 07:49 edited on: 2020-06-05 07:50 |
Quotesrc/core/json.cpp | 272 ++++++++++++++++--------- src/core/json.h | 272 ++++++++----------------- Quotesrc/wadseeker/protocols/json.cpp | 274 +++++++++++------- src/wadseeker/protocols/json.h | 272 ++++++----------- I hadn't noticed this before, but huh. Despite the line differences in json.cpp, but show to be the same json.cpp file in the master branch and my patch branch. |
(0021354) WubTheCaptain (reporter) 2020-06-05 07:51 edited on: 2020-06-05 07:52 |
0003794:0021353:Quote from WubTheCaptain Nevermind, git diff doesn't catch it but diff -u does. $ diff -u src/core/json.cpp src/wadseeker/protocols/json.cpp # master branch --- src/core/json.cpp 2020-06-05 07:48:38.577780264 +0000 +++ src/wadseeker/protocols/json.cpp 2020-06-05 07:48:38.577780264 +0000 @@ -468,11 +468,11 @@ index = lastIndex + 1; if (numberStr.contains('.')) { - return QVariant(numberStr.toDouble(NULL)); + return QVariant(numberStr.toDouble(nullptr)); } else if (numberStr.startsWith('-')) { - return QVariant(numberStr.toLongLong(NULL)); + return QVariant(numberStr.toLongLong(nullptr)); } else { - return QVariant(numberStr.toULongLong(NULL)); + return QVariant(numberStr.toULongLong(nullptr)); } } |
(0021408) Blzut3 (administrator) 2020-06-08 01:50 |
Given that Qt JSON was added years before we added support for Qt5 much less dropped Qt4 support, should we instead have a ticket for switching to Qt 5's own JSON classes? |
(0021415) WubTheCaptain (reporter) 2020-06-08 02:31 |
Quote from Blzut3 Unaware those existed, yes. 0003821 (excuse the summary). 'https://doc.qt.io/qt-5/json.html [^]' |
This issue is already marked as resolved. If you feel that is not the case, please reopen it and explain why. |
|
Supporters: | No one explicitly supports this issue yet. |
Opponents: | No one explicitly opposes this issue yet. |
Issue History | |||
Date Modified | Username | Field | Change |
2020-06-05 07:05 | WubTheCaptain | New Issue | |
2020-06-05 07:05 | WubTheCaptain | Status | new => assigned |
2020-06-05 07:05 | WubTheCaptain | Assigned To | => WubTheCaptain |
2020-06-05 07:06 | WubTheCaptain | File Added: 0001-qt-json-Update-to-commit-aa0930a.patch | |
2020-06-05 07:06 | WubTheCaptain | Status | assigned => needs review |
2020-06-05 07:16 | WubTheCaptain | File Added: 0002-Update-qt-json-in-wadseeker-too.patch | |
2020-06-05 07:17 | WubTheCaptain | Note Added: 0021351 | |
2020-06-05 07:19 | WubTheCaptain | File Deleted: 0002-Update-qt-json-in-wadseeker-too.patch | |
2020-06-05 07:22 | WubTheCaptain | File Added: 0002-Update-qt-json-in-wadseeker-too.patch | |
2020-06-05 07:25 | WubTheCaptain | Note Added: 0021352 | |
2020-06-05 07:33 | WubTheCaptain | Assigned To | WubTheCaptain => |
2020-06-05 07:49 | WubTheCaptain | Note Added: 0021353 | |
2020-06-05 07:49 | WubTheCaptain | Note Edited: 0021353 | View Revisions |
2020-06-05 07:50 | WubTheCaptain | Note Edited: 0021353 | View Revisions |
2020-06-05 07:51 | WubTheCaptain | Note Added: 0021354 | |
2020-06-05 07:52 | WubTheCaptain | Note Edited: 0021354 | View Revisions |
2020-06-05 08:31 | WubTheCaptain | Assigned To | => WubTheCaptain |
2020-06-05 08:31 | WubTheCaptain | Status | needs review => assigned |
2020-06-05 08:34 | WubTheCaptain | File Added: 0003-Fix-QtJson-parse-class-reference-in-freedoominfopars.patch | |
2020-06-05 08:35 | WubTheCaptain | Assigned To | WubTheCaptain => |
2020-06-05 08:35 | WubTheCaptain | Status | assigned => needs review |
2020-06-07 02:29 | WubTheCaptain | Relationship added | related to 0003803 |
2020-06-08 01:50 | Blzut3 | Note Added: 0021408 | |
2020-06-08 02:31 | WubTheCaptain | Note Added: 0021415 | |
2020-06-08 02:31 | WubTheCaptain | Status | needs review => resolved |
2020-06-08 02:31 | WubTheCaptain | Resolution | open => won't fix |
2020-06-08 02:31 | WubTheCaptain | Assigned To | => WubTheCaptain |
2020-06-08 02:31 | WubTheCaptain | Relationship added | related to 0003821 |
2021-08-07 16:52 | Blzut3 | Status | resolved => closed |
2021-08-16 19:10 | WubTheCaptain | Target Version | 1.3.3 => 1.3.2 |
Copyright © 2012-2024, Torr Samaho & Zandronum Team.
Doom and Doom II are the property of id Software.
Copyright © 2000 - 2024 MantisBT Team |