diff --git a/CMakeLists.txt b/CMakeLists.txt index 49123ee..8ff8660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_DEBUG_POSTFIX _debug) # Declare project project(qtjsonsettings) -find_package(Qt4 REQUIRED) +find_package(Qt5 REQUIRED) set(QT_DONTUSE_QTGUI TRUE) include(${QT_USE_FILE}) @@ -30,14 +30,13 @@ message("You are linking ${PROJECT_NAME}. I hope it makes your life easier.") # SOURCE FILES AND DIRECTORIES # simple sources -list(APPEND qtjsonsettings_SOURCES qtjsonsettings.cpp json.cpp jsonparser.cpp) +list(APPEND qtjsonsettings_SOURCES qtjsonsettings.cpp) # simple headers -list(APPEND qtjsonsettings_HEADERS json.h) list(APPEND qtjsonsettings_Q_HEADERS qtjsonsettings.h) # if you use Q_OBJECT -qt4_wrap_cpp(qtjsonsettings_MOC_SOURCES ${qtjsonsettings_Q_HEADERS}) +qt5_wrap_cpp(qtjsonsettings_MOC_SOURCES ${qtjsonsettings_Q_HEADERS}) # COMPILATION add_library(${PROJECT_NAME} STATIC diff --git a/json.cpp b/json.cpp deleted file mode 100644 index 7c3ac95..0000000 --- a/json.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (c) 2010 Girish Ramakrishnan - ** - ** 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 ()) - { - result = QByteArray::number(variant.toLongLong()); - } - else if (variant.canConvert ()) - { - 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 ()) - { - result = QByteArray::number(variant.toLongLong()); - } - else if (variant.canConvert ()) - { - result = stringify(variant); - } - break; - } - } - - return result; - } -} - diff --git a/json.h b/json.h deleted file mode 100644 index f075dc9..0000000 --- a/json.h +++ /dev/null @@ -1,23 +0,0 @@ -/**************************************************************************** -** -** Copyright (c) 2010 Girish Ramakrishnan -** -** Use, modification and distribution is allowed without limitation, -** warranty, liability or support of any kind. -** -****************************************************************************/ - -#ifndef JSON_H -#define JSON_H - -#include -#include - -namespace Json { - QVariant parse(const QByteArray &data, QString *error = 0); - QByteArray stringify(const QVariant &variant); - QByteArray prettyStringify(const QVariant &variant, int indent = 4, int indent0 = 0); -}; - -#endif // JSON_H - diff --git a/jsonparser.cpp b/jsonparser.cpp deleted file mode 100644 index 5593c4f..0000000 --- a/jsonparser.cpp +++ /dev/null @@ -1,469 +0,0 @@ -// This file was generated by qlalr - DO NOT EDIT! -#ifndef JSONPARSER_CPP -#define JSONPARSER_CPP - -class JsonGrammar -{ -public: - enum VariousConstants { - EOF_SYMBOL = 0, - ERROR = 12, - T_COLON = 7, - T_COMMA = 8, - T_FALSE = 9, - T_LCURLYBRACKET = 3, - T_LSQUAREBRACKET = 5, - T_NULL = 11, - T_NUMBER = 2, - T_RCURLYBRACKET = 4, - T_RSQUAREBRACKET = 6, - T_STRING = 1, - T_TRUE = 10, - - ACCEPT_STATE = 12, - RULE_COUNT = 18, - STATE_COUNT = 26, - TERMINAL_COUNT = 13, - NON_TERMINAL_COUNT = 8, - - GOTO_INDEX_OFFSET = 26, - GOTO_INFO_OFFSET = 37, - GOTO_CHECK_OFFSET = 37 - }; - - static const char *const spell []; - static const short lhs []; - static const short rhs []; - -#ifndef QLALR_NO_JSONGRAMMAR_DEBUG_INFO - static const int rule_index []; - static const int rule_info []; -#endif // QLALR_NO_JSONGRAMMAR_DEBUG_INFO - - static const short goto_default []; - static const short action_default []; - static const short action_index []; - static const short action_info []; - static const short action_check []; - - static inline int nt_action (int state, int nt) - { - const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt; - if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt) - return goto_default [nt]; - - return action_info [GOTO_INFO_OFFSET + yyn]; - } - - static inline int t_action (int state, int token) - { - const int yyn = action_index [state] + token; - - if (yyn < 0 || action_check [yyn] != token) - return - action_default [state]; - - return action_info [yyn]; - } -}; - - -const char *const JsonGrammar::spell [] = { - "end of file", "string", "number", "{", "}", "[", "]", ":", ",", "false", - "true", "null", "error", -#ifndef QLALR_NO_JSONGRAMMAR_DEBUG_INFO -"Root", "Value", "Object", "Members", "Member", "Array", "Values", - "$accept" -#endif // QLALR_NO_JSONGRAMMAR_DEBUG_INFO -}; - -const short JsonGrammar::lhs [] = { - 13, 15, 16, 16, 16, 17, 14, 14, 14, 14, - 14, 14, 14, 18, 19, 19, 19, 20}; - -const short JsonGrammar::rhs [] = { - 1, 3, 1, 3, 0, 3, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 3, 0, 2}; - - -#ifndef QLALR_NO_JSONGRAMMAR_DEBUG_INFO -const int JsonGrammar::rule_info [] = { - 13, 14 - , 15, 3, 16, 4 - , 16, 17 - , 16, 16, 8, 17 - , 16 - , 17, 1, 7, 14 - , 14, 9 - , 14, 10 - , 14, 11 - , 14, 15 - , 14, 18 - , 14, 2 - , 14, 1 - , 18, 5, 19, 6 - , 19, 14 - , 19, 19, 8, 14 - , 19 - , 20, 13, 0}; - -const int JsonGrammar::rule_index [] = { - 0, 2, 6, 8, 12, 13, 17, 19, 21, 23, - 25, 27, 29, 31, 35, 37, 41, 42}; -#endif // QLALR_NO_JSONGRAMMAR_DEBUG_INFO - -const short JsonGrammar::action_default [] = { - 0, 11, 10, 0, 7, 5, 17, 9, 12, 13, - 8, 1, 18, 3, 0, 0, 0, 2, 4, 0, - 6, 15, 0, 0, 14, 16}; - -const short JsonGrammar::goto_default [] = { - 3, 11, 2, 14, 13, 1, 22, 0}; - -const short JsonGrammar::action_index [] = { - 24, -13, -13, 0, -13, 12, 24, -13, -13, -13, - -13, -13, -13, -13, -1, -6, 12, -13, -13, 7, - -13, -13, -4, 24, -13, -13, - - -8, -8, -8, -8, -8, -8, -1, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -2, -8, -8, 0, - -8, -8, -8, 6, -8, -8}; - -const short JsonGrammar::action_info [] = { - 12, 19, 24, 17, 23, 0, 0, 16, 9, 8, - 5, 0, 6, 15, 0, 0, 4, 10, 7, 0, - 0, 0, 0, 0, 0, 9, 8, 5, 0, 6, - 0, 0, 0, 4, 10, 7, 0, - - 21, 20, 18, 0, 0, 0, 0, 25, 0, 0, - 0, 0, 0, 0}; - -const short JsonGrammar::action_check [] = { - 0, 7, 6, 4, 8, -1, -1, 8, 1, 2, - 3, -1, 5, 1, -1, -1, 9, 10, 11, -1, - -1, -1, -1, -1, -1, 1, 2, 3, -1, 5, - -1, -1, -1, 9, 10, 11, -1, - - 1, 1, 4, -1, -1, -1, -1, 1, -1, -1, - -1, -1, -1, -1}; - - -#line 28 "json.g" - -/**************************************************************************** -** -** Copyright (c) 2010 Girish Ramakrishnan -** -** Use, modification and distribution is allowed without limitation, -** warranty, liability or support of any kind. -** -****************************************************************************/ - -#ifndef JSONPARSER_P_H -#define JSONPARSER_P_H - -#include -#include -#include - -class JsonLexer -{ -public: - JsonLexer(const QByteArray &data); - ~JsonLexer(); - - int lex(); - QVariant symbol() const { return m_symbol; } - int lineNumber() const { return m_lineNumber; } - int pos() const { return m_pos; } - -private: - int parseNumber(); - int parseString(); - int parseKeyword(); - - QByteArray m_data; - int m_lineNumber; - int m_pos; - QVariant m_symbol; - QHash m_keywords; -}; - -class JsonParser : protected JsonGrammar -{ -public: - JsonParser(); - ~JsonParser(); - - bool parse(JsonLexer *lex); - QVariant result() const { return m_result; } - QString errorMessage() const { return QString("%1 at line %2 pos %3").arg(m_errorMessage).arg(m_errorLineNumber).arg(m_errorPos); } - -private: - void reallocateStack(); - - inline QVariant &sym(int index) - { return m_symStack[m_tos + index - 1]; } - - int m_tos; - QVector m_stateStack; - QVector m_symStack; - QString m_errorMessage; - int m_errorLineNumber; - int m_errorPos; - QVariant m_result; -}; - -#endif // JSONPARSER_P_H - -#line 96 "json.g" - -/**************************************************************************** -** -** Copyright (c) 2010 Girish Ramakrishnan -** -** Use, modification and distribution is allowed without limitation, -** warranty, liability or support of any kind. -** -****************************************************************************/ - -#include - -JsonLexer::JsonLexer(const QByteArray &ba) - : m_data(ba), m_lineNumber(1), m_pos(0) -{ - m_keywords.insert("true", JsonGrammar::T_TRUE); - m_keywords.insert("false", JsonGrammar::T_FALSE); - m_keywords.insert("null", JsonGrammar::T_NULL); -} - -JsonLexer::~JsonLexer() -{ -} - -int JsonLexer::parseString() -{ - QString str; - bool esc = false; - ++m_pos; // skip initial " - for (; m_pos < m_data.length(); ++m_pos) { - const char c = m_data[m_pos]; - if (esc) { - if (c == 'b') str += '\b'; - else if (c == 'f') str += '\f'; - else if (c == 'n') str += '\n'; - else if (c == 'r') str += '\r'; - else if (c == 't') str += '\t'; - else if (c == '\\') str += '\\'; - else if (c == '\"') str += '\"'; - else if (c == 'u' && m_pos+4= '0' && c <= '9')) - continue; - if (c == '.' || c == 'e' || c == 'E') { - isDouble = true; - continue; - } - break; - } - QByteArray number = QByteArray::fromRawData(m_data.constData()+start, m_pos-start); - bool ok; - if (!isDouble) { - m_symbol = number.toInt(&ok); - if (!ok) - m_symbol = number.toLongLong(&ok); - } - if (isDouble || !ok) - m_symbol = number.toDouble(); - return JsonGrammar::T_NUMBER; -} - -int JsonLexer::parseKeyword() -{ - int start = m_pos; - for (; m_pos < m_data.length(); ++m_pos) { - const char c = m_data[m_pos]; - if (c >= 'a' && c <= 'z') - continue; - break; - } - QByteArray keyword = QByteArray::fromRawData(m_data.constData()+start, m_pos-start); - if (m_keywords.contains(keyword)) - return m_keywords.value(keyword); - return JsonGrammar::ERROR; -} - -int JsonLexer::lex() -{ - m_symbol.clear(); - while (m_pos < m_data.length()) { - const char c = m_data[m_pos]; - switch (c) { - case '[': ++m_pos; return JsonGrammar::T_LSQUAREBRACKET; - case ']': ++m_pos; return JsonGrammar::T_RSQUAREBRACKET; - case '{': ++m_pos; return JsonGrammar::T_LCURLYBRACKET; - case '}': ++m_pos; return JsonGrammar::T_RCURLYBRACKET; - case ':': ++m_pos; return JsonGrammar::T_COLON; - case ',': ++m_pos; return JsonGrammar::T_COMMA; - case ' ': case '\r': case '\t': case 'b': ++m_pos; break; - case '\n': ++m_pos; ++m_lineNumber; break; - case '"': return parseString(); - default: - if (c == '+' || c == '-' || (c >= '0' && c <= '9')) { - return parseNumber(); - } - if (c >= 'a' && c <= 'z') { - return parseKeyword(); - } - return JsonGrammar::ERROR; - } - } - return JsonGrammar::EOF_SYMBOL; -} - -JsonParser::JsonParser() -{ -} - -JsonParser::~JsonParser() -{ -} - -void JsonParser::reallocateStack() -{ - int size = m_stateStack.size(); - if (size == 0) - size = 128; - else - size <<= 1; - m_symStack.resize(size); - m_stateStack.resize(size); -} - -bool JsonParser::parse(JsonLexer *lexer) -{ - const int INITIAL_STATE = 0; - int yytoken = -1; - reallocateStack(); - m_tos = 0; - m_stateStack[++m_tos] = INITIAL_STATE; - - while (true) { - const int state = m_stateStack[m_tos]; - if (yytoken == -1 && -TERMINAL_COUNT != action_index[state]) { - yytoken = lexer->lex(); - } - int act = t_action(state, yytoken); - if (act == ACCEPT_STATE) - return true; - else if (act > 0) { - if (++m_tos == m_stateStack.size()) - reallocateStack(); - m_stateStack[m_tos] = act; - m_symStack[m_tos] = lexer->symbol(); - yytoken = -1; - } else if (act < 0) { - int r = -act-1; - m_tos -= rhs[r]; - act = m_stateStack.at(m_tos++); - switch (r) { - -#line 276 "json.g" - case 0: { m_result = sym(1); break; } -#line 279 "json.g" - case 1: { sym(1) = sym(2); break; } -#line 284 "json.g" - case 3: { sym(1) = sym(1).toMap().unite(sym(3).toMap()); break; } -#line 287 "json.g" - case 4: { sym(1) = QVariantMap(); break; } -#line 290 "json.g" - case 5: { QVariantMap map; map.insert(sym(1).toString(), sym(3)); sym(1) = map; break; } -#line 293 "json.g" - case 6: { sym(1) = QVariant(false); break; } -#line 296 "json.g" - case 7: { sym(1) = QVariant(true); break; } -#line 305 "json.g" - case 13: { sym(1) = sym(2); break; } -#line 308 "json.g" - case 14: { QVariantList list; list.append(sym(1)); sym(1) = list; break; } -#line 311 "json.g" - case 15: { QVariantList list = sym(1).toList(); list.append(sym(3)); sym(1) = list; break; } -#line 314 "json.g" - case 16: { sym(1) = QVariantList(); break; } -#line 316 "json.g" - - } // switch - m_stateStack[m_tos] = nt_action(act, lhs[r] - TERMINAL_COUNT); - } else { - int ers = state; - int shifts = 0; - int reduces = 0; - int expected_tokens[3]; - for (int tk = 0; tk < TERMINAL_COUNT; ++tk) { - int k = t_action(ers, tk); - - if (! k) - continue; - else if (k < 0) - ++reduces; - else if (spell[tk]) { - if (shifts < 3) - expected_tokens[shifts] = tk; - ++shifts; - } - } - - m_errorLineNumber = lexer->lineNumber(); - m_errorPos = lexer->pos(); - m_errorMessage.clear(); - if (shifts && shifts < 3) { - bool first = true; - - for (int s = 0; s < shifts; ++s) { - if (first) - m_errorMessage += QLatin1String("Expected "); - else - m_errorMessage += QLatin1String(", "); - - first = false; - m_errorMessage += QLatin1String("'"); - m_errorMessage += QLatin1String(spell[expected_tokens[s]]); - m_errorMessage += QLatin1String("'"); - } - } - return false; - } - } - - return false; -} - - -#endif // JSONPARSER_CPP - diff --git a/qtjsonsettings.cpp b/qtjsonsettings.cpp index 71845c4..526944a 100644 --- a/qtjsonsettings.cpp +++ b/qtjsonsettings.cpp @@ -1,10 +1,6 @@ #include "qtjsonsettings.h" - -#include "json.h" - #include - -#include +#include namespace { @@ -14,9 +10,9 @@ namespace { { case QVariant::Map: { - QVariantMap vMap = element.toMap(); - QVariantMap::ConstIterator it = vMap.constBegin(); - QVariantMap::ConstIterator end = vMap.constEnd(); + auto vMap = element.toMap(); + auto it = vMap.constBegin(); + auto end = vMap.constEnd(); for (; it != end; ++it) { @@ -88,16 +84,19 @@ const QSettings::Format QtJsonSettings::json_format = QSettings::registerFormat( bool QtJsonSettings::readJsonFile(QIODevice &device, QSettings::SettingsMap &map) { - QString error; - QVariant parsed = Json::parse(device.readAll(), &error); - if (error.isEmpty()) + QJsonParseError error; + auto document = QJsonDocument::fromJson(device.readAll(), &error); + + if (QJsonParseError::NoError == error.error) { - QString str; - processReadKey(str, map, parsed); + if (!document.isEmpty()){ + QString str; + processReadKey(str, map, document.toVariant()); + } } else { - qWarning() << error; + qWarning() << error.errorString(); } return true; @@ -107,15 +106,15 @@ bool QtJsonSettings::writeJsonFile(QIODevice &device, const QSettings::SettingsM { QVariant resultMap; - QSettings::SettingsMap::ConstIterator it = map.constBegin(); - QSettings::SettingsMap::ConstIterator end = map.constEnd(); + auto it = map.constBegin(); + auto end = map.constEnd(); for (; it != end; ++it) { resultMap = processWriteKey(resultMap, it.key(), it.value()); }; - device.write(Json::prettyStringify(resultMap, 4)); + device.write(QJsonDocument::fromVariant(resultMap).toJson()); return true; } diff --git a/qtjsonsettings.h b/qtjsonsettings.h index e5a8261..b9abf55 100755 --- a/qtjsonsettings.h +++ b/qtjsonsettings.h @@ -16,9 +16,9 @@ class QIODevice; #endif /** - * @brief Class for storing application setting in xml file. This class implements QSettings interface. + * @brief Class for storing application setting in json file. This class implements QSettings interface. * - * @class QtXmlSettings qtxmlsettings.h + * @class QtJsonSettings qtjsonsettings.h */ class QTJSONSETTINGS_EXPORT QtJsonSettings: public QSettings { diff --git a/qtjsonsettings.pri b/qtjsonsettings.pri index 58b5900..146a7d5 100644 --- a/qtjsonsettings.pri +++ b/qtjsonsettings.pri @@ -3,6 +3,3 @@ DEPENDPATH += $$PWD HEADERS += $$PWD/qtjsonsettings.h SOURCES += $$PWD/qtjsonsettings.cpp - -HEADERS += $$PWD/json.h -SOURCES += $$PWD/json.cpp $$PWD/jsonparser.cpp