Simple Json implementation: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Decode HTML entity names)
m (fix indentation after migration)
Line 1: Line 1:
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}
[[Category:Snippets]]
[[Category:Snippets]]
[toc align_right="yes" depth="3"]
= Simple JSON Implementation =
= Simple JSON Implementation =


Line 10: Line 6:
== JsonObject.hpp ==
== JsonObject.hpp ==


<code>#ifndef JSONOBJECT_HPP
<code>
#ifndef JSONOBJECT_HPP
#define JSONOBJECT_HPP
#define JSONOBJECT_HPP


Line 20: Line 17:
{
{
public:
public:
static const QString null;
    static const QString null;
static const QString True;
    static const QString True;
static const QString False;
    static const QString False;
 
   
JsonObject(QString jsonData = "");
    JsonObject(QString jsonData = "");
 
   
QString toString() const;
    QString toString() const;
 
   
void put(const QString& id,JsonObject obj);
    void put(const QString& id,JsonObject obj);
void put(const QString& id,QString value);
    void put(const QString& id,QString value);
void put(const QString& id,int value);
    void put(const QString& id,int value);
void put(const QString& id,double value);
    void put(const QString& id,double value);
void put(const QString& id,qlonglong value);
    void put(const QString& id,qlonglong value);
void put(const QString& id,JsonArray value);
    void put(const QString& id,JsonArray value);
 
   
JsonObject getObject(const QString& id, bool *ok = NULL) const;
    JsonObject getObject(const QString& id, bool *ok = NULL) const;
QString getString(const QString& id, bool *ok = NULL) const;
    QString getString(const QString& id, bool *ok = NULL) const;
int getInt(const QString& id, bool *ok = NULL) const;
    int getInt(const QString& id, bool *ok = NULL) const;
double getDouble(const QString& id, bool *ok = NULL) const;
    double getDouble(const QString& id, bool *ok = NULL) const;
qlonglong getLong(const QString& id, bool *ok = NULL) const;
    qlonglong getLong(const QString& id, bool *ok = NULL) const;
JsonArray getArray(const QString& id, bool *ok = NULL) const;
    JsonArray getArray(const QString& id, bool *ok = NULL) const;
 
   
bool isNull(const QString& id) const;
    bool isNull(const QString& id) const;
 
   
QVariantMap getRawData() const;
    QVariantMap getRawData() const;
protected:
protected:
void setRawData(QVariantMap data);
    void setRawData(QVariantMap data);
 
   
private:
private:
QString stringFromList(const JsonArray& array) const;
    QString stringFromList(const JsonArray& array) const;
QString getKey(QString& data);
    QString getKey(QString& data);
QString getValue(QString& data);
    QString getValue(QString& data);
JsonArray parseArray(QString data);
    JsonArray parseArray(QString data);
 
   
QVariantMap objectData;
    QVariantMap objectData;
};
};


Line 64: Line 61:
== JsonObject.cpp ==
== JsonObject.cpp ==


<code>#include "JsonObject.hpp"
<code>
#include "JsonObject.hpp"
#include <QStringList>
#include <QStringList>


QString JsonObject::toString() const
QString JsonObject::toString() const
{
{
QString result = "{";
    QString result = "{";
QStringList keys = objectData.keys();
    QStringList keys = objectData.keys();
for(int i = 0; i < keys.count(); +''i)
    for(int i = 0; i < keys.count(); +''i)
{
    {
QVariant data = objectData.value(keys.at(i));
        QVariant data = objectData.value(keys.at(i));
switch(data.type())
        switch(data.type())
{
        {
case QVariant::Map:
        case QVariant::Map:
{
        {
result.append('"');
            result.append('"');
result.append(keys.at(i));
            result.append(keys.at(i));
result.append('"');
            result.append('"');
result.append(':');
            result.append(':');
JsonObject obj;
            JsonObject obj;
obj.setRawData(data.toMap());
            obj.setRawData(data.toMap());
result.append(obj.toString());
            result.append(obj.toString());
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::String:
        case QVariant::String:
{
        {
result.append('"');
            result.append('"');
result.append(keys.at(i));
            result.append(keys.at(i));
result.append('"');
            result.append('"');
result.append(':');
            result.append(':');
if(data.toString()  null || data.toString()  True
            if(data.toString()  null || data.toString()  True
|| data.toString() == False)
                    || data.toString() == False)
result.append(data.toString());
                result.append(data.toString());
else
            else
{
            {
result.append('"');
                result.append('"');
result.append(data.toString());
                result.append(data.toString());
result.append('"');
                result.append('"');
}
            }
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::Int:
        case QVariant::Int:
{
        {
result.append('"');
            result.append('"');
result.append(keys.at(i));
            result.append(keys.at(i));
result.append('"');
            result.append('"');
result.append(':');
            result.append(':');
result.append(QString("%1").arg(data.toInt()));
            result.append(QString("%1").arg(data.toInt()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::Double:
        case QVariant::Double:
{
        {
result.append('"');
            result.append('"');
result.append(keys.at(i));
            result.append(keys.at(i));
result.append('"');
            result.append('"');
result.append(':');
            result.append(':');
result.append(QString("%1").arg(data.toDouble()));
            result.append(QString("%1").arg(data.toDouble()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::LongLong:
        case QVariant::LongLong:
{
        {
result.append('"');
            result.append('"');
result.append(keys.at(i));
            result.append(keys.at(i));
result.append('"');
            result.append('"');
result.append(':');
            result.append(':');
result.append(QString("%1").arg(data.toLongLong()));
            result.append(QString("%1").arg(data.toLongLong()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::List:
        case QVariant::List:
{
        {
result.append('"');
            result.append('"');
result.append(keys.at(i));
            result.append(keys.at(i));
result.append('"');
            result.append('"');
result.append(':');
            result.append(':');
result.append(stringFromList(data.toList()));
            result.append(stringFromList(data.toList()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
default:
        default:
break;
            break;
}
        }
}
    }
if(result.endsWith(','))
    if(result.endsWith(','))
result.remove(result.length() - 1,1);
        result.remove(result.length() - 1,1);
result.append("}");
    result.append("}");
return result;
    return result;
}
}


void JsonObject::put(const QString& id,JsonObject obj)
void JsonObject::put(const QString& id,JsonObject obj)
{
{
objectData.insert(id,QVariant(obj.getRawData()));
    objectData.insert(id,QVariant(obj.getRawData()));
}
}


void JsonObject::put(const QString& id,QString value)
void JsonObject::put(const QString& id,QString value)
{
{
if(value.startsWith('"'))
    if(value.startsWith('"'))
value.remove(0,1);
        value.remove(0,1);
if(value.endsWith('"'))
    if(value.endsWith('"'))
value.remove(value.length() - 1,1);
        value.remove(value.length() - 1,1);
objectData.insert(id,QVariant(value));
    objectData.insert(id,QVariant(value));
}
}


void JsonObject::put(const QString& id,int value)
void JsonObject::put(const QString& id,int value)
{
{
objectData.insert(id,QVariant(value));
    objectData.insert(id,QVariant(value));
}
}


void JsonObject::put(const QString& id,double value)
void JsonObject::put(const QString& id,double value)
{
{
objectData.insert(id,QVariant(value));
    objectData.insert(id,QVariant(value));
}
}


void JsonObject::put(const QString& id,qlonglong value)
void JsonObject::put(const QString& id,qlonglong value)
{
{
objectData.insert(id,QVariant(value));
    objectData.insert(id,QVariant(value));
}
}


void JsonObject::put(const QString& id,JsonArray value)
void JsonObject::put(const QString& id,JsonArray value)
{
{
objectData.insert(id,QVariant(value));
    objectData.insert(id,QVariant(value));
}
}


JsonObject JsonObject::getObject(const QString& id, bool *ok) const
JsonObject JsonObject::getObject(const QString& id, bool *ok) const
{
{
JsonObject result;
    JsonObject result;
bool isOk = false;
    bool isOk = false;
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
QVariant data = objectData.value(id);
        QVariant data = objectData.value(id);
if(data.type() == QVariant::Map)
        if(data.type() == QVariant::Map)
{
        {
result.setRawData(data.toMap());
            result.setRawData(data.toMap());
isOk = true;
            isOk = true;
}
        }
}
    }
if(ok != NULL)
    if(ok != NULL)
*ok = isOk;
        *ok = isOk;
return result;
    return result;
}
}


QString JsonObject::getString(const QString& id, bool *ok) const
QString JsonObject::getString(const QString& id, bool *ok) const
{
{
QString result = "";
    QString result = "";
bool isOk = false;
    bool isOk = false;
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
QVariant data = objectData.value(id);
        QVariant data = objectData.value(id);
if(data.type() == QVariant::String)
        if(data.type() == QVariant::String)
{
        {
result = data.toString();
            result = data.toString();
isOk = true;
            isOk = true;
}
        }
}
    }
if(ok != NULL)
    if(ok != NULL)
*ok = isOk;
        *ok = isOk;
return result;
    return result;
}
}


int JsonObject::getInt(const QString& id, bool *ok) const
int JsonObject::getInt(const QString& id, bool *ok) const
{
{
int result = 0;
    int result = 0;
bool isOk = false;
    bool isOk = false;
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
QVariant data = objectData.value(id);
        QVariant data = objectData.value(id);
if(data.type() == QVariant::Int)
        if(data.type() == QVariant::Int)
{
        {
result = data.toInt();
            result = data.toInt();
isOk = true;
            isOk = true;
}
        }
}
    }
if(ok != NULL)
    if(ok != NULL)
*ok = isOk;
        *ok = isOk;
return result;
    return result;
}
}


double JsonObject::getDouble(const QString& id, bool *ok) const
double JsonObject::getDouble(const QString& id, bool *ok) const
{
{
double result = 0.0;
    double result = 0.0;
bool isOk = false;
    bool isOk = false;
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
QVariant data = objectData.value(id);
        QVariant data = objectData.value(id);
if(data.type() == QVariant::Double)
        if(data.type() == QVariant::Double)
{
        {
result = data.toDouble();
            result = data.toDouble();
isOk = true;
            isOk = true;
}
        }
}
    }
if(ok != NULL)
    if(ok != NULL)
*ok = isOk;
        *ok = isOk;
return result;
    return result;
}
}


qlonglong JsonObject::getLong(const QString& id, bool *ok) const
qlonglong JsonObject::getLong(const QString& id, bool *ok) const
{
{
qlonglong result = 0;
    qlonglong result = 0;
bool isOk = false;
    bool isOk = false;
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
QVariant data = objectData.value(id);
        QVariant data = objectData.value(id);
if(data.type() == QVariant::LongLong)
        if(data.type() == QVariant::LongLong)
{
        {
result = data.toLongLong();
            result = data.toLongLong();
isOk = true;
            isOk = true;
}
        }
}
    }
if(ok != NULL)
    if(ok != NULL)
*ok = isOk;
        *ok = isOk;
return result;
    return result;
}
}


JsonArray JsonObject::getArray(const QString& id, bool *ok) const
JsonArray JsonObject::getArray(const QString& id, bool *ok) const
{
{
JsonArray result;
    JsonArray result;
bool isOk = false;
    bool isOk = false;
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
QVariant data = objectData.value(id);
        QVariant data = objectData.value(id);
if(data.type() == QVariant::List)
        if(data.type() == QVariant::List)
{
        {
result = data.toList();
            result = data.toList();
isOk = true;
            isOk = true;
}
        }
}
    }
if(ok != NULL)
    if(ok != NULL)
*ok = isOk;
        *ok = isOk;
return result;
    return result;
}
}


bool JsonObject::isNull(const QString& id) const
bool JsonObject::isNull(const QString& id) const
{
{
if(objectData.contains(id))
    if(objectData.contains(id))
{
    {
if(objectData.value(id).type()  QVariant::String)
        if(objectData.value(id).type()  QVariant::String)
             return objectData.value(id).toString()  null;
             return objectData.value(id).toString()  null;
return false;
        return false;
}
    }
return true;
    return true;
}
}


QVariantMap JsonObject::getRawData() const
QVariantMap JsonObject::getRawData() const
{
{
return objectData;
    return objectData;
}
}


void JsonObject::setRawData(QVariantMap data)
void JsonObject::setRawData(QVariantMap data)
{
{
objectData = data;
    objectData = data;
}
}


QString JsonObject::stringFromList(const JsonArray& array) const
QString JsonObject::stringFromList(const JsonArray& array) const
{
{
QString result = "[";
    QString result = "[";
for(int i = 0; i < array.count();i)
    for(int i = 0; i < array.count();i)
{
    {
QVariant data = array.at(i);
        QVariant data = array.at(i);
switch(data.type())
        switch(data.type())
{
        {
case QVariant::Map:
        case QVariant::Map:
{
        {
JsonObject obj;
            JsonObject obj;
obj.setRawData(data.toMap());
            obj.setRawData(data.toMap());
result.append(obj.toString());
            result.append(obj.toString());
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::String:
        case QVariant::String:
{
        {
if(data.toString()  null || data.toString()  False || data.toString() == True)
            if(data.toString()  null || data.toString()  False || data.toString() == True)
result.append(data.toString());
                result.append(data.toString());
else
            else
{
            {
result.append('"');
                result.append('"');
result.append(data.toString());
                result.append(data.toString());
result.append('"');
                result.append('"');
}
            }
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::Int:
        case QVariant::Int:
{
        {
result.append(QString("%1").arg(data.toInt()));
            result.append(QString("%1").arg(data.toInt()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::Double:
        case QVariant::Double:
{
        {
result.append(QString("%1").arg(data.toDouble()));
            result.append(QString("%1").arg(data.toDouble()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::LongLong:
        case QVariant::LongLong:
{
        {
result.append(QString("%1").arg(data.toLongLong()));
            result.append(QString("%1").arg(data.toLongLong()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
case QVariant::List:
        case QVariant::List:
{
        {
result.append(stringFromList(data.toList()));
            result.append(stringFromList(data.toList()));
result.append(',');
            result.append(',');
}
        }
break;
            break;
default:
        default:
break;
            break;
}
        }
}
    }
if(result.endsWith(','))
    if(result.endsWith(','))
result.remove(result.length() - 1,1);
        result.remove(result.length() - 1,1);
result.append("]");
    result.append("]");
return result;
    return result;
}
}


QString JsonObject::getKey(QString& data)
QString JsonObject::getKey(QString& data)
{
{
QString key = "";
    QString key = "";
int index = data.indexOf(':');
    int index = data.indexOf(':');
if(index >= 0)
    if(index >= 0)
{
    {
key = data.mid(0,index);
        key = data.mid(0,index);
data.remove(0,index);
        data.remove(0,index);
if(data.startsWith(':'))
        if(data.startsWith(':'))
data.remove(0,1);
            data.remove(0,1);
}
    }
if(key.startsWith('"'))
    if(key.startsWith('"'))
key.remove(0,1);
        key.remove(0,1);
if(key.endsWith('"'))
    if(key.endsWith('"'))
key.remove(key.length() - 1,1);
        key.remove(key.length() - 1,1);
return key;
    return key;
}
}


QString JsonObject::getValue(QString& data)
QString JsonObject::getValue(QString& data)
{
{
QString value = "";
    QString value = "";
if(data.startsWith('{'))//object
    if(data.startsWith('{'))//object
{
    {
int index = data.indexOf('}');
        int index = data.indexOf('}');
if(index >= 0)
        if(index >= 0)
{
        {
value.append(data.mid(0,index'' 1));
            value.append(data.mid(0,index'' 1));
data.remove(0,index + 1);
            data.remove(0,index + 1);
while(value.count('{') > value.count('}'))
            while(value.count('{') > value.count('}'))
{
            {
index = data.indexOf('}');
                index = data.indexOf('}');
if(index >= 0)
                if(index >= 0)
{
                {
value.append(data.mid(0,index + 1));
                    value.append(data.mid(0,index + 1));
data.remove(0,index + 1);
                    data.remove(0,index + 1);
}
                }
else
                else
{
                {
value = "";
                    value = "";
break;
                    break;
}
                }
}
            }
if(data.startsWith(','))
            if(data.startsWith(','))
data.remove(0,1);
                data.remove(0,1);
}
        }
}
    }
else if(data.startsWith('['))//Array
    else if(data.startsWith('['))//Array
{
    {
int index = data.indexOf(']');
        int index = data.indexOf(']');
if(index >= 0)
        if(index >= 0)
{
        {
value.append(data.mid(0,index + 1));
            value.append(data.mid(0,index + 1));
data.remove(0,index + 1);
            data.remove(0,index + 1);
while(value.count('[') > value.count(']'))
            while(value.count('[') > value.count(']'))
{
            {
index = data.indexOf(']');
                index = data.indexOf(']');
if(index >= 0)
                if(index >= 0)
{
                {
value.append(data.mid(0,index + 1));
                    value.append(data.mid(0,index + 1));
data.remove(0,index + 1);
                    data.remove(0,index + 1);
}
                }
else
                else
{
                {
value = "";
                    value = "";
break;
                    break;
}
                }
}
            }
if(data.startsWith(','))
            if(data.startsWith(','))
data.remove(0,1);
                data.remove(0,1);
}
        }
}
    }
else
    else
{
    {
int index = data.indexOf(',');
        int index = data.indexOf(',');
if(index >= 0)
        if(index >= 0)
{
        {
value = data.mid(0,index);
            value = data.mid(0,index);
data.remove(0,index);
            data.remove(0,index);
if(data.startsWith(','))
            if(data.startsWith(','))
data.remove(0,1);
                data.remove(0,1);
}
        }
else if(!data.contains(','))
        else if(!data.contains(','))
{
        {
value = data;
            value = data;
data.clear();
            data.clear();
}
        }
}
    }
return value;
    return value;
}
}


JsonArray JsonObject::parseArray(QString data)
JsonArray JsonObject::parseArray(QString data)
{
{
JsonArray result;
    JsonArray result;
if(data.startsWith('[') && data.endsWith(']'))
    if(data.startsWith('[') && data.endsWith(']'))
{
    {
data.remove(0,1);
        data.remove(0,1);
data.remove(data.length() - 1,1);
        data.remove(data.length() - 1,1);
while(data.length() > 0)
        while(data.length() > 0)
{
        {
QString value = getValue(data);
            QString value = getValue(data);
if(value.startsWith('{'))//Object
            if(value.startsWith('{'))//Object
{
            {
JsonObject obj(value);
                JsonObject obj(value);
result.append(QVariant(obj.getRawData()));
                result.append(QVariant(obj.getRawData()));
}
            }
else if(value.startsWith('['))//Array
            else if(value.startsWith('['))//Array
{
            {
JsonArray array = parseArray(value);
                JsonArray array = parseArray(value);
result.append(QVariant(array));
                result.append(QVariant(array));
}
            }
else if(value.startsWith('"'))//String
            else if(value.startsWith('"'))//String
{
            {
value.remove(0,1);
                value.remove(0,1);
if(value.endsWith('"'))
                if(value.endsWith('"'))
value.remove(value.length() - 1,1);
                    value.remove(value.length() - 1,1);
result.append(QVariant(value));
                result.append(QVariant(value));
}
            }
else if(value  null)
            else if(value  null)
                 result.append(QVariant(null));
                 result.append(QVariant(null));
             else if(value  True)
             else if(value  True)
result.append(QVariant(True));
                result.append(QVariant(True));
else if(value == False)
            else if(value == False)
result.append(QVariant(False));
                result.append(QVariant(False));
else//Number
            else//Number
{
            {
if(value.contains('.'))//double
                if(value.contains('.'))//double
{
                {
bool ok;
                    bool ok;
double doubleValue = value.toDouble(&ok);
                    double doubleValue = value.toDouble(&ok);
if(ok)
                    if(ok)
result.append(QVariant(doubleValue));
                        result.append(QVariant(doubleValue));
else
                    else
result.append(QVariant(0.0));
                        result.append(QVariant(0.0));
}
                }
else//int || long
                else//int || long
{
                {
bool ok;
                    bool ok;
int intValue = value.toInt(&ok);
                    int intValue = value.toInt(&ok);
if(ok)
                    if(ok)
result.append(QVariant(intValue));
                        result.append(QVariant(intValue));
else
                    else
{
                    {
qlonglong longValue = value.toLongLong(&ok);
                        qlonglong longValue = value.toLongLong(&ok);
if(ok)
                        if(ok)
result.append(QVariant(longValue));
                            result.append(QVariant(longValue));
else
                        else
result.append(QVariant(0));
                            result.append(QVariant(0));
}
                    }
}
                }
}
            }
}
        }
}
    }
return result;
    return result;
}
}


JsonObject::JsonObject(QString jsonData)
JsonObject::JsonObject(QString jsonData)
{
{
if(jsonData.startsWith('{') && jsonData.endsWith('}'))
    if(jsonData.startsWith('{') && jsonData.endsWith('}'))
{
    {
jsonData.remove(0,1);
        jsonData.remove(0,1);
jsonData.remove(jsonData.length() - 1,1);
        jsonData.remove(jsonData.length() - 1,1);
while(jsonData.length() > 0)
        while(jsonData.length() > 0)
{
        {
QString key = getKey(jsonData);
            QString key = getKey(jsonData);
QString value = getValue(jsonData);
            QString value = getValue(jsonData);
if(value.startsWith('{'))//Object
            if(value.startsWith('{'))//Object
this->put(key,JsonObject(value));
                this->put(key,JsonObject(value));
else if(value.startsWith('['))//Array
            else if(value.startsWith('['))//Array
{
            {
JsonArray array = parseArray(value);
                JsonArray array = parseArray(value);
this->put(key,array);
                this->put(key,array);
}
            }
else if(value.startsWith('"'))//String
            else if(value.startsWith('"'))//String
this->put(key,value);
                this->put(key,value);
else if(value  null)
            else if(value  null)
                 this->put(key,null);
                 this->put(key,null);
             else if(value  True)
             else if(value  True)
this->put(key,True);
                this->put(key,True);
else if(value == False)
            else if(value == False)
this->put(key,False);
                this->put(key,False);
else//Number
            else//Number
{
            {
if(value.contains('.'))//double
                if(value.contains('.'))//double
{
                {
bool ok;
                    bool ok;
double doubleValue = value.toDouble(&ok);
                    double doubleValue = value.toDouble(&ok);
if(ok)
                    if(ok)
this->put(key,doubleValue);
                        this->put(key,doubleValue);
else
                    else
this->put(key,0.0);
                        this->put(key,0.0);
}
                }
else//int || long
                else//int || long
{
                {
bool ok;
                    bool ok;
int intValue = value.toInt(&ok);
                    int intValue = value.toInt(&ok);
if(ok)
                    if(ok)
this->put(key,intValue);
                        this->put(key,intValue);
else
                    else
{
                    {
qlonglong longValue = value.toLongLong(&ok);
                        qlonglong longValue = value.toLongLong(&ok);
if(ok)
                        if(ok)
this->put(key,longValue);
                            this->put(key,longValue);
else
                        else
this->put(key,0);
                            this->put(key,0);
}
                    }
}
                }
}
            }
}
        }
}
    }
}
}


Line 596: Line 594:
const QString JsonObject::True = "true";
const QString JsonObject::True = "true";
const QString JsonObject::False = "false";
const QString JsonObject::False = "false";
</code>

Revision as of 15:48, 31 March 2015

Simple JSON Implementation

The reason I made this (except for the fun of it) is that I found a couple of people had issues with incorporating QJson in their projects (be it what it may). I reserve no copyrights to this implementation so you are all welcome to ctrl+c ctrl+v and do as you see fit with it.

JsonObject.hpp

#ifndef JSONOBJECT_HPP
#define JSONOBJECT_HPP

#include <QVariant>

typedef QVariantList JsonArray;

class JsonObject
{
public:
    static const QString null;
    static const QString True;
    static const QString False;
    
    JsonObject(QString jsonData = "");
    
    QString toString() const;
    
    void put(const QString& id,JsonObject obj);
    void put(const QString& id,QString value);
    void put(const QString& id,int value);
    void put(const QString& id,double value);
    void put(const QString& id,qlonglong value);
    void put(const QString& id,JsonArray value);
    
    JsonObject getObject(const QString& id, bool *ok = NULL) const;
    QString getString(const QString& id, bool *ok = NULL) const;
    int getInt(const QString& id, bool *ok = NULL) const;
    double getDouble(const QString& id, bool *ok = NULL) const;
    qlonglong getLong(const QString& id, bool *ok = NULL) const;
    JsonArray getArray(const QString& id, bool *ok = NULL) const;
    
    bool isNull(const QString& id) const;
    
    QVariantMap getRawData() const;
protected:
    void setRawData(QVariantMap data);
    
private:
    QString stringFromList(const JsonArray& array) const;
    QString getKey(QString& data);
    QString getValue(QString& data);
    JsonArray parseArray(QString data);
    
    QVariantMap objectData;
};

#endif // JSONOBJECT_HPP

Here's the cpp code:

JsonObject.cpp

#include "JsonObject.hpp"
#include <QStringList>

QString JsonObject::toString() const
{
    QString result = "{";
    QStringList keys = objectData.keys();
    for(int i = 0; i < keys.count(); +''i)
    {
        QVariant data = objectData.value(keys.at(i));
        switch(data.type())
        {
        case QVariant::Map:
        {
            result.append('"');
            result.append(keys.at(i));
            result.append('"');
            result.append(':');
            JsonObject obj;
            obj.setRawData(data.toMap());
            result.append(obj.toString());
            result.append(',');
        }
            break;
        case QVariant::String:
        {
            result.append('"');
            result.append(keys.at(i));
            result.append('"');
            result.append(':');
            if(data.toString()  null || data.toString()  True
                    || data.toString() == False)
                result.append(data.toString());
            else
            {
                result.append('"');
                result.append(data.toString());
                result.append('"');
            }
            result.append(',');
        }
            break;
        case QVariant::Int:
        {
            result.append('"');
            result.append(keys.at(i));
            result.append('"');
            result.append(':');
            result.append(QString("%1").arg(data.toInt()));
            result.append(',');
        }
            break;
        case QVariant::Double:
        {
            result.append('"');
            result.append(keys.at(i));
            result.append('"');
            result.append(':');
            result.append(QString("%1").arg(data.toDouble()));
            result.append(',');
        }
            break;
        case QVariant::LongLong:
        {
            result.append('"');
            result.append(keys.at(i));
            result.append('"');
            result.append(':');
            result.append(QString("%1").arg(data.toLongLong()));
            result.append(',');
        }
            break;
        case QVariant::List:
        {
            result.append('"');
            result.append(keys.at(i));
            result.append('"');
            result.append(':');
            result.append(stringFromList(data.toList()));
            result.append(',');
        }
            break;
        default:
            break;
        }
    }
    if(result.endsWith(','))
        result.remove(result.length() - 1,1);
    result.append("}");
    return result;
}

void JsonObject::put(const QString& id,JsonObject obj)
{
    objectData.insert(id,QVariant(obj.getRawData()));
}

void JsonObject::put(const QString& id,QString value)
{
    if(value.startsWith('"'))
        value.remove(0,1);
    if(value.endsWith('"'))
        value.remove(value.length() - 1,1);
    objectData.insert(id,QVariant(value));
}

void JsonObject::put(const QString& id,int value)
{
    objectData.insert(id,QVariant(value));
}

void JsonObject::put(const QString& id,double value)
{
    objectData.insert(id,QVariant(value));
}

void JsonObject::put(const QString& id,qlonglong value)
{
    objectData.insert(id,QVariant(value));
}

void JsonObject::put(const QString& id,JsonArray value)
{
    objectData.insert(id,QVariant(value));
}

JsonObject JsonObject::getObject(const QString& id, bool *ok) const
{
    JsonObject result;
    bool isOk = false;
    if(objectData.contains(id))
    {
        QVariant data = objectData.value(id);
        if(data.type() == QVariant::Map)
        {
            result.setRawData(data.toMap());
            isOk = true;
        }
    }
    if(ok != NULL)
        *ok = isOk;
    return result;
}

QString JsonObject::getString(const QString& id, bool *ok) const
{
    QString result = "";
    bool isOk = false;
    if(objectData.contains(id))
    {
        QVariant data = objectData.value(id);
        if(data.type() == QVariant::String)
        {
            result = data.toString();
            isOk = true;
        }
    }
    if(ok != NULL)
        *ok = isOk;
    return result;
}

int JsonObject::getInt(const QString& id, bool *ok) const
{
    int result = 0;
    bool isOk = false;
    if(objectData.contains(id))
    {
        QVariant data = objectData.value(id);
        if(data.type() == QVariant::Int)
        {
            result = data.toInt();
            isOk = true;
        }
    }
    if(ok != NULL)
        *ok = isOk;
    return result;
}

double JsonObject::getDouble(const QString& id, bool *ok) const
{
    double result = 0.0;
    bool isOk = false;
    if(objectData.contains(id))
    {
        QVariant data = objectData.value(id);
        if(data.type() == QVariant::Double)
        {
            result = data.toDouble();
            isOk = true;
        }
    }
    if(ok != NULL)
        *ok = isOk;
    return result;
}

qlonglong JsonObject::getLong(const QString& id, bool *ok) const
{
    qlonglong result = 0;
    bool isOk = false;
    if(objectData.contains(id))
    {
        QVariant data = objectData.value(id);
        if(data.type() == QVariant::LongLong)
        {
            result = data.toLongLong();
            isOk = true;
        }
    }
    if(ok != NULL)
        *ok = isOk;
    return result;
}

JsonArray JsonObject::getArray(const QString& id, bool *ok) const
{
    JsonArray result;
    bool isOk = false;
    if(objectData.contains(id))
    {
        QVariant data = objectData.value(id);
        if(data.type() == QVariant::List)
        {
            result = data.toList();
            isOk = true;
        }
    }
    if(ok != NULL)
        *ok = isOk;
    return result;
}

bool JsonObject::isNull(const QString& id) const
{
    if(objectData.contains(id))
    {
        if(objectData.value(id).type()  QVariant::String)
            return objectData.value(id).toString()  null;
        return false;
    }
    return true;
}

QVariantMap JsonObject::getRawData() const
{
    return objectData;
}

void JsonObject::setRawData(QVariantMap data)
{
    objectData = data;
}

QString JsonObject::stringFromList(const JsonArray& array) const
{
    QString result = "[";
    for(int i = 0; i < array.count();i)
    {
        QVariant data = array.at(i);
        switch(data.type())
        {
        case QVariant::Map:
        {
            JsonObject obj;
            obj.setRawData(data.toMap());
            result.append(obj.toString());
            result.append(',');
        }
            break;
        case QVariant::String:
        {
            if(data.toString()  null || data.toString()  False || data.toString() == True)
                result.append(data.toString());
            else
            {
                result.append('"');
                result.append(data.toString());
                result.append('"');
            }
            result.append(',');
        }
            break;
        case QVariant::Int:
        {
            result.append(QString("%1").arg(data.toInt()));
            result.append(',');
        }
            break;
        case QVariant::Double:
        {
            result.append(QString("%1").arg(data.toDouble()));
            result.append(',');
        }
            break;
        case QVariant::LongLong:
        {
            result.append(QString("%1").arg(data.toLongLong()));
            result.append(',');
        }
            break;
        case QVariant::List:
        {
            result.append(stringFromList(data.toList()));
            result.append(',');
        }
            break;
        default:
            break;
        }
    }
    if(result.endsWith(','))
        result.remove(result.length() - 1,1);
    result.append("]");
    return result;
}

QString JsonObject::getKey(QString& data)
{
    QString key = "";
    int index = data.indexOf(':');
    if(index >= 0)
    {
        key = data.mid(0,index);
        data.remove(0,index);
        if(data.startsWith(':'))
            data.remove(0,1);
    }
    if(key.startsWith('"'))
        key.remove(0,1);
    if(key.endsWith('"'))
        key.remove(key.length() - 1,1);
    return key;
}

QString JsonObject::getValue(QString& data)
{
    QString value = "";
    if(data.startsWith('{'))//object
    {
        int index = data.indexOf('}');
        if(index >= 0)
        {
            value.append(data.mid(0,index'' 1));
            data.remove(0,index + 1);
            while(value.count('{') > value.count('}'))
            {
                index = data.indexOf('}');
                if(index >= 0)
                {
                    value.append(data.mid(0,index + 1));
                    data.remove(0,index + 1);
                }
                else
                {
                    value = "";
                    break;
                }
            }
            if(data.startsWith(','))
                data.remove(0,1);
        }
    }
    else if(data.startsWith('['))//Array
    {
        int index = data.indexOf(']');
        if(index >= 0)
        {
            value.append(data.mid(0,index + 1));
            data.remove(0,index + 1);
            while(value.count('[') > value.count(']'))
            {
                index = data.indexOf(']');
                if(index >= 0)
                {
                    value.append(data.mid(0,index + 1));
                    data.remove(0,index + 1);
                }
                else
                {
                    value = "";
                    break;
                }
            }
            if(data.startsWith(','))
                data.remove(0,1);
        }
    }
    else
    {
        int index = data.indexOf(',');
        if(index >= 0)
        {
            value = data.mid(0,index);
            data.remove(0,index);
            if(data.startsWith(','))
                data.remove(0,1);
        }
        else if(!data.contains(','))
        {
            value = data;
            data.clear();
        }
    }
    return value;
}

JsonArray JsonObject::parseArray(QString data)
{
    JsonArray result;
    if(data.startsWith('[') && data.endsWith(']'))
    {
        data.remove(0,1);
        data.remove(data.length() - 1,1);
        while(data.length() > 0)
        {
            QString value = getValue(data);
            if(value.startsWith('{'))//Object
            {
                JsonObject obj(value);
                result.append(QVariant(obj.getRawData()));
            }
            else if(value.startsWith('['))//Array
            {
                JsonArray array = parseArray(value);
                result.append(QVariant(array));
            }
            else if(value.startsWith('"'))//String
            {
                value.remove(0,1);
                if(value.endsWith('"'))
                    value.remove(value.length() - 1,1);
                result.append(QVariant(value));
            }
            else if(value  null)
                result.append(QVariant(null));
            else if(value  True)
                result.append(QVariant(True));
            else if(value == False)
                result.append(QVariant(False));
            else//Number
            {
                if(value.contains('.'))//double
                {
                    bool ok;
                    double doubleValue = value.toDouble(&ok);
                    if(ok)
                        result.append(QVariant(doubleValue));
                    else
                        result.append(QVariant(0.0));
                }
                else//int || long
                {
                    bool ok;
                    int intValue = value.toInt(&ok);
                    if(ok)
                        result.append(QVariant(intValue));
                    else
                    {
                        qlonglong longValue = value.toLongLong(&ok);
                        if(ok)
                            result.append(QVariant(longValue));
                        else
                            result.append(QVariant(0));
                    }
                }
            }
        }
    }
    return result;
}

JsonObject::JsonObject(QString jsonData)
{
    if(jsonData.startsWith('{') && jsonData.endsWith('}'))
    {
        jsonData.remove(0,1);
        jsonData.remove(jsonData.length() - 1,1);
        while(jsonData.length() > 0)
        {
            QString key = getKey(jsonData);
            QString value = getValue(jsonData);
            if(value.startsWith('{'))//Object
                this->put(key,JsonObject(value));
            else if(value.startsWith('['))//Array
            {
                JsonArray array = parseArray(value);
                this->put(key,array);
            }
            else if(value.startsWith('"'))//String
                this->put(key,value);
            else if(value  null)
                this->put(key,null);
            else if(value  True)
                this->put(key,True);
            else if(value == False)
                this->put(key,False);
            else//Number
            {
                if(value.contains('.'))//double
                {
                    bool ok;
                    double doubleValue = value.toDouble(&ok);
                    if(ok)
                        this->put(key,doubleValue);
                    else
                        this->put(key,0.0);
                }
                else//int || long
                {
                    bool ok;
                    int intValue = value.toInt(&ok);
                    if(ok)
                        this->put(key,intValue);
                    else
                    {
                        qlonglong longValue = value.toLongLong(&ok);
                        if(ok)
                            this->put(key,longValue);
                        else
                            this->put(key,0);
                    }
                }
            }
        }
    }
}

const QString JsonObject::null = "null";
const QString JsonObject::True = "true";
const QString JsonObject::False = "false";