1
0
This repository has been archived on 2024-09-13. You can view files and clone it, but cannot push or open issues or pull requests.
qtjsonsettings/json.cpp

288 lines
8.0 KiB
C++
Raw Normal View History

2011-03-05 20:37:24 +00:00
/****************************************************************************
**
** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
**
** Use, modification and distribution is allowed without limitation,
** warranty, liability or support of any kind.
**
****************************************************************************/
#include "json.h"
#include "jsonparser.cpp"
namespace Json {
QVariant parse(const QByteArray &json, QString *error)
{
JsonLexer lexer(json);
JsonParser parser;
if (!parser.parse(&lexer) && error)
{
*error = parser.errorMessage();
}
return parser.result();
}
static QByteArray escape(const QVariant &variant)
{
QString str = variant.toString();
QByteArray res;
res.reserve(str.length());
for (int i = 0; i < str.length(); i++)
{
if (str[i] == '\b')
{
res += "\\b";
}
else if (str[i] == '\f')
{
res += "\\f";
}
else if (str[i] == '\n')
{
res += "\\n";
}
else if (str[i] == '\r')
{
res += "\\r";
}
else if (str[i] == '\t')
{
res += "\\t";
}
else if (str[i] == '\"')
{
res += "\\\"";
}
else if (str[i] == '\\')
{
res += "\\\\";
}
else if (str[i].unicode() > 127)
{
res += "\\u" + QString::number(str[i].unicode(), 16).rightJustified(4, '0');
}
else
{
res += str[i].toAscii();
}
}
return res;
}
QByteArray stringify(const QVariant &variant)
{
QByteArray result;
if (variant.type() == QVariant::List || variant.type() == QVariant::StringList)
{
result += "[";
QVariantList list = variant.toList();
for (int i = 0; i < list.count(); i++)
{
if (i != 0)
result += ",";
result += stringify(list[i]);
}
result += "]";
}
else if (variant.type() == QVariant::Map)
{
QVariantMap map = variant.toMap();
QVariantMap::const_iterator it = map.constBegin();
result += "{";
while (it != map.constEnd())
{
if (it != map.constBegin())
result += ",";
result += "\"" + escape(it.key()) + "\":";
result += stringify(it.value());
++it;
}
result += "}";
}
else if (variant.type() == QVariant::String || variant.type() == QVariant::ByteArray)
{
result = "\"" + escape(variant) + "\"";
}
else if (variant.type() == QVariant::Double || (int) variant.type() == (int) QMetaType::Float)
{
result.setNum(variant.toDouble(), 'g', 15);
}
else if (variant.type() == QVariant::Bool)
{
result = variant.toBool() ? "true" : "false";
}
else if (variant.type() == QVariant::Invalid)
{
result = "null";
}
else if (variant.type() == QVariant::ULongLong)
{
result = QByteArray::number(variant.toULongLong());
}
else if (variant.type() == QVariant::LongLong)
{
result = QByteArray::number(variant.toLongLong());
}
else if (variant.type() == QVariant::Int)
{
result = QByteArray::number(variant.toInt());
}
else if (variant.type() == QVariant::UInt)
{
result = QByteArray::number(variant.toUInt());
}
else if (variant.type() == QVariant::Char)
{
QChar c = variant.toChar();
if (c.unicode() > 127)
result = "\\u" + QByteArray::number(c.unicode(), 16).rightJustified(4, '0');
else
result.append(c.toAscii());
}
else if (variant.canConvert<qlonglong> ())
{
result = QByteArray::number(variant.toLongLong());
}
else if (variant.canConvert<QString> ())
{
result = stringify(variant);
}
return result;
}
QByteArray prettyStringify(const QVariant &variant, int indent, int indent0)
{
QByteArray result;
QString indentstr0 = QString(indent0, ' ');
QString indentstr = QString(indent0 + indent, ' ');
switch ((int) variant.type())
{
case QVariant::List:
case QVariant::StringList:
{
result += indentstr0;
result += "[\n";
QVariantList list = variant.toList();
for (int i = 0; i < list.count(); i++)
{
if (i != 0)
result += ",\n";
if (list[i].type() != QVariant::Map && list[i].type() != QVariant::List && list[i].type()
!= QVariant::StringList)
result += indentstr;
result += prettyStringify(list[i], indent, indent0 + indent);
}
result += "\n";
result += indentstr0;
result += "]";
break;
}
case QVariant::Map:
{
QVariantMap map = variant.toMap();
QVariantMap::const_iterator it = map.constBegin();
result += indentstr0;
result += "{\n";
while (it != map.constEnd())
{
if (it != map.constBegin())
result += ",\n";
result += indentstr;
result += "\"" + escape(it.key()) + "\":";
if (it.value().type() == QVariant::Map || it.value().type() == QVariant::List || it.value().type()
== QVariant::StringList)
{
result += "\n";
}
result += prettyStringify(it.value(), indent, indent0 + indent);
++it;
}
result += "\n";
result += indentstr0;
result += "}";
break;
}
case QVariant::String:
case QVariant::ByteArray:
{
result = "\"" + escape(variant) + "\"";
break;
}
case QVariant::Double:
case QMetaType::Float:
{
result = QString::number(variant.toDouble(), 'g', 15).toUtf8();
break;
}
case QVariant::Bool:
{
result = variant.toBool() ? "true" : "false";
break;
}
case QVariant::Invalid:
{
result = "null";
break;
}
case QVariant::ULongLong:
{
result = QByteArray::number(variant.toULongLong());
break;
}
case QVariant::LongLong:
{
result = QByteArray::number(variant.toLongLong());
break;
}
case QVariant::Int:
{
result = QByteArray::number(variant.toInt());
break;
}
case QVariant::UInt:
{
result = QByteArray::number(variant.toUInt());
break;
}
case QVariant::Char:
{
QChar c = variant.toChar();
if (c.unicode() > 127)
result = "\\u" + QByteArray::number(c.unicode(), 16).rightJustified(4, '0');
else
result.append(c.toAscii());
break;
}
default:
{
if (variant.canConvert<qlonglong> ())
{
result = QByteArray::number(variant.toLongLong());
}
else if (variant.canConvert<QString> ())
{
result = stringify(variant);
}
break;
}
}
return result;
}
}