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

