Simple Json implementation: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Sub-categorize; it's also a HowTo)
(Redirect to identical page)
 
Line 1: Line 1:
[[Category:Snippets::Misc]]
#Redirect [[Simple JSON Implementation]]
[[Category:HowTo]]
The reason I made this (except for the fun of it) is that I found a couple of people had issues with incorporating [http://qjson.sourceforge.net/ 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 ==
 
<code>
#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
</code>
 
Here's the cpp code:
 
== JsonObject.cpp ==
 
<code>
#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";
</code>

Latest revision as of 12:18, 28 November 2016