From 557b999608b14738e5d7955db0dc6a5aedf30636 Mon Sep 17 00:00:00 2001 From: Syping Date: Wed, 29 Mar 2023 17:12:32 +0200 Subject: [PATCH] replace json serializer with boost, libragephoto upstream --- .gitmodules | 3 + CMakeLists.txt | 3 + src/JsonEditorDialog.cpp | 33 ++++--- src/JsonEditorDialog.h | 2 +- src/SnapmaticJson.cpp | 123 +++++++++++++++++++++++++ src/SnapmaticJson.h | 33 +++++++ src/SnapmaticPicture.cpp | 191 +++++++++++++++++++++++---------------- src/SnapmaticPicture.h | 21 ++--- src/json | 1 + src/libragephoto | 2 +- 10 files changed, 308 insertions(+), 104 deletions(-) create mode 100644 src/SnapmaticJson.cpp create mode 100644 src/SnapmaticJson.h create mode 160000 src/json diff --git a/.gitmodules b/.gitmodules index f8ce4e3..fd97fcd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "src/libragephoto"] path = src/libragephoto url = https://github.com/Syping/libragephoto.git +[submodule "src/json"] +path = src/json +url = https://github.com/boostorg/json.git diff --git a/CMakeLists.txt b/CMakeLists.txt index c168872..7d9b102 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ set(GTA5VIEW_SOURCES src/SavegameWidget.cpp src/SidebarGenerator.cpp src/SnapmaticEditor.cpp + src/SnapmaticJson.cpp src/SnapmaticPicture.cpp src/SnapmaticWidget.cpp src/StandardPaths.cpp @@ -121,6 +122,7 @@ set(GTA5VIEW_HEADERS src/SavegameWidget.h src/SidebarGenerator.h src/SnapmaticEditor.h + src/SnapmaticJson.h src/SnapmaticPicture.h src/SnapmaticWidget.h src/StandardPaths.h @@ -137,6 +139,7 @@ set(GTA5VIEW_HEADERS set(GTA5VIEW_INCLUDEDIR src src/anpro + src/json/include src/pcg src/uimod ) diff --git a/src/JsonEditorDialog.cpp b/src/JsonEditorDialog.cpp index 13cd5b4..25c8ca0 100644 --- a/src/JsonEditorDialog.cpp +++ b/src/JsonEditorDialog.cpp @@ -19,6 +19,7 @@ #include "JsonEditorDialog.h" #include "ui_JsonEditorDialog.h" #include "SnapmaticEditor.h" +#include "SnapmaticJson.h" #include "AppEnv.h" #include "config.h" #include @@ -63,7 +64,7 @@ JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) : ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save")); } - jsonCode = picture->getJsonStr(); + jsonCode = picture->getJsonStdStr(); #if QT_VERSION >= 0x050200 ui->txtJSON->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); @@ -80,9 +81,9 @@ JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) : ui->txtJSON->setTabStopWidth(fontMetrics.width(" ")); #endif - QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonCode.toUtf8()); + const boost::json::value jsonValue = boost::json::parse(jsonCode); ui->txtJSON->setStyleSheet("QPlainTextEdit{background-color: rgb(46, 47, 48); color: rgb(238, 231, 172);}"); - ui->txtJSON->setPlainText(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Indented)).trimmed()); + ui->txtJSON->setPlainText(QString::fromUtf8(SnapmaticJson::serialize(jsonValue, true).c_str())); jsonHl = new JSHighlighter(ui->txtJSON->document()); // DPI calculation @@ -112,11 +113,14 @@ JsonEditorDialog::~JsonEditorDialog() void JsonEditorDialog::closeEvent(QCloseEvent *ev) { - QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " "); - QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8()); - QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8()); - QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact)); - QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact)); + const QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", ""); + std::error_code ec; + const boost::json::value jsonNew = boost::json::parse(jsonPatched.toUtf8().constData(), ec); + const boost::json::value jsonOriginal = boost::json::parse(jsonCode, ec); + const std::string newCode = SnapmaticJson::serialize(jsonNew); + const std::string originalCode = SnapmaticJson::serialize(jsonOriginal); + qDebug() << newCode.c_str(); + qDebug() << originalCode.c_str(); if (newCode != originalCode) { QMessageBox::StandardButton button = QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("

Unsaved changes detected

You want to save the JSON content before you quit?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel); if (button == QMessageBox::Yes) { @@ -141,12 +145,13 @@ void JsonEditorDialog::closeEvent(QCloseEvent *ev) bool JsonEditorDialog::saveJsonContent() { - QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " "); - QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8()); - if (!jsonNew.isEmpty()) { - QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8()); - QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact)); - QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact)); + const QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", ""); + std::error_code ec; + const boost::json::value jsonNew = boost::json::parse(jsonPatched.toUtf8().constData(), ec); + if (jsonNew.is_object()) { + const boost::json::value jsonOriginal = boost::json::parse(jsonCode, ec); + const std::string newCode = SnapmaticJson::serialize(jsonNew); + const std::string originalCode = SnapmaticJson::serialize(jsonOriginal); if (newCode != originalCode) { QString currentFilePath = smpic->getPictureFilePath(); QString originalFilePath = smpic->getOriginalPictureFilePath(); diff --git a/src/JsonEditorDialog.h b/src/JsonEditorDialog.h index 4e618bb..f9a12e1 100644 --- a/src/JsonEditorDialog.h +++ b/src/JsonEditorDialog.h @@ -47,7 +47,7 @@ signals: void codeUpdated(QString jsonCode); private: - QString jsonCode; + std::string jsonCode; JSHighlighter *jsonHl; SnapmaticPicture *smpic; Ui::JsonEditorDialog *ui; diff --git a/src/SnapmaticJson.cpp b/src/SnapmaticJson.cpp new file mode 100644 index 0000000..aad6f0e --- /dev/null +++ b/src/SnapmaticJson.cpp @@ -0,0 +1,123 @@ +/***************************************************************************** +* gta5view Grand Theft Auto V Profile Viewer +* Copyright (C) 2023 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include +#include +#include "SnapmaticJson.h" + +void serializer(std::ostream &os, const boost::json::value &jv, std::string *indent, bool do_indent) +{ + std::string indent_; + if (!indent) + indent = &indent_; + switch (jv.kind()) { + case boost::json::kind::object: { + if (do_indent) { + os << "{\n"; + indent->append(4, ' '); + } + else + os << "{"; + auto const &obj = jv.get_object(); + if (!obj.empty()) { + auto it = obj.begin(); + for (;;) { + if (do_indent) + os << *indent << boost::json::serialize(it->key()) << ": "; + else + os << boost::json::serialize(it->key()) << ":"; + serializer(os, it->value(), indent, do_indent); + if (++it == obj.end()) + break; + if (do_indent) + os << ",\n"; + else + os << ","; + } + } + if (do_indent) { + os << "\n"; + indent->resize(indent->size() - 4); + os << *indent << "}"; + } + else + os << "}"; + break; + } + case boost::json::kind::array: { + if (do_indent) { + os << "[\n"; + indent->append(4, ' '); + } + else + os << "["; + auto const &arr = jv.get_array(); + if (!arr.empty()) { + auto it = arr.begin(); + for (;;) { + if (do_indent) + os << *indent; + serializer(os, *it, indent, do_indent); + if (++it == arr.end()) + break; + if (do_indent) + os << ",\n"; + else + os << ","; + } + } + if (do_indent) { + os << "\n"; + indent->resize(indent->size() - 4); + os << *indent << "]"; + } + else + os << "]"; + break; + } + case boost::json::kind::string: { + os << boost::json::serialize(jv.get_string()); + break; + } + case boost::json::kind::uint64: + os << jv.get_uint64(); + break; + case boost::json::kind::int64: + os << jv.get_int64(); + break; + case boost::json::kind::double_: + os << jv.get_double(); + break; + case boost::json::kind::bool_: + if (jv.get_bool()) + os << "true"; + else + os << "false"; + break; + case boost::json::kind::null: + os << "null"; + break; + } +} + +std::string SnapmaticJson::serialize(const boost::json::value &jv, bool do_indent) +{ + std::ostringstream buffer; + serializer(buffer, jv, nullptr, do_indent); + return buffer.str(); +} diff --git a/src/SnapmaticJson.h b/src/SnapmaticJson.h new file mode 100644 index 0000000..1b95114 --- /dev/null +++ b/src/SnapmaticJson.h @@ -0,0 +1,33 @@ +/***************************************************************************** +* gta5view Grand Theft Auto V Profile Viewer +* Copyright (C) 2023 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SNAPMATICJSON_H +#define SNAPMATICJSON_H +#ifndef Q_MOC_RUN + +#include + +class SnapmaticJson +{ +public: + static std::string serialize(const boost::json::value &jv, bool do_indent = false); + boost::json::object jsonObject; +}; + +#endif // Q_MOC_RUN +#endif // SNAPMATICJSON_H diff --git a/src/SnapmaticPicture.cpp b/src/SnapmaticPicture.cpp index ede89f3..973b224 100644 --- a/src/SnapmaticPicture.cpp +++ b/src/SnapmaticPicture.cpp @@ -18,8 +18,6 @@ #include "SnapmaticPicture.h" #include -#include -#include #include #include #include @@ -449,8 +447,8 @@ void SnapmaticPicture::reset() // SNAPMATIC PROPERTIES localProperties = {}; - // JSON OBJECT - jsonObject = QJsonObject(); + // JSON VALUE + snapmaticJson.jsonObject = boost::json::object(); } bool SnapmaticPicture::preloadFile() @@ -567,15 +565,17 @@ bool SnapmaticPicture::preloadFile() return false; } - const QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_ragePhoto.json()); - if (t_jsonDocument.isNull()) - return false; - jsonObject = t_jsonDocument.object(); + if (!picFilePath.endsWith(".g5e", Qt::CaseInsensitive) && p_ragePhoto.format() == G5EPhotoFormat::G5EX) + isFormatSwitch = true; + + std::error_code ec; + boost::json::value jsonValue = boost::json::parse(p_ragePhoto.json(), ec); + if (ec) + return false; + if (!jsonValue.is_object()) + return false; + snapmaticJson.jsonObject = jsonValue.get_object(); - if (!picFilePath.endsWith(".g5e", Qt::CaseInsensitive)) { - if (p_ragePhoto.format() == G5EPhotoFormat::G5EX) - isFormatSwitch = true; - } isPreLoaded = true; emit preloaded(); return ok; @@ -867,6 +867,11 @@ const QString SnapmaticPicture::getJsonStr() return QString::fromUtf8(p_ragePhoto.json()); } +const std::string SnapmaticPicture::getJsonStdStr() +{ + return std::string(p_ragePhoto.json()); +} + SnapmaticProperties SnapmaticPicture::getSnapmaticProperties() { return localProperties; @@ -875,25 +880,31 @@ SnapmaticProperties SnapmaticPicture::getSnapmaticProperties() void SnapmaticPicture::parseJsonContent() { const uint32_t format = p_ragePhoto.format(); - QVariantMap jsonMap = jsonObject.toVariantMap(); + const boost::json::object &t_jsonObject = snapmaticJson.jsonObject; bool jsonIncomplete = false; bool jsonError = false; - if (jsonObject.contains("loc")) { - if (jsonObject["loc"].isObject()) { - QJsonObject locObject = jsonObject["loc"].toObject(); + if (t_jsonObject.contains("loc")) { + if (t_jsonObject.at("loc").is_object()) { + const boost::json::object locObject = t_jsonObject.at("loc").get_object(); if (locObject.contains("x")) { - if (locObject["x"].isDouble()) { localProperties.location.x = locObject["x"].toDouble(); } + if (locObject.at("x").is_double()) { localProperties.location.x = locObject.at("x").get_double(); } + else if (locObject.at("x").is_int64()) { localProperties.location.x = static_cast(locObject.at("x").get_int64()); } + else if (locObject.at("x").is_uint64()) { localProperties.location.x = static_cast(locObject.at("x").get_uint64()); } else { jsonError = true; } } else { jsonIncomplete = true; } if (locObject.contains("y")) { - if (locObject["y"].isDouble()) { localProperties.location.y = locObject["y"].toDouble(); } + if (locObject.at("y").is_double()) { localProperties.location.y = locObject.at("y").get_double(); } + else if (locObject.at("y").is_int64()) { localProperties.location.x = static_cast(locObject.at("y").get_int64()); } + else if (locObject.at("y").is_uint64()) { localProperties.location.x = static_cast(locObject.at("y").get_uint64()); } else { jsonError = true; } } else { jsonIncomplete = true; } if (locObject.contains("z")) { - if (locObject["z"].isDouble()) { localProperties.location.z = locObject["z"].toDouble(); } + if (locObject.at("z").is_double()) { localProperties.location.z = locObject.at("z").get_double(); } + else if (locObject.at("z").is_int64()) { localProperties.location.x = static_cast(locObject.at("z").get_int64()); } + else if (locObject.at("z").is_uint64()) { localProperties.location.x = static_cast(locObject.at("z").get_uint64()); } else { jsonError = true; } } else { jsonIncomplete = true; } @@ -901,74 +912,87 @@ void SnapmaticPicture::parseJsonContent() else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("uid")) { - bool uidOk; - localProperties.uid = jsonMap["uid"].toInt(&uidOk); - if (!uidOk) { jsonError = true; } + if (t_jsonObject.contains("uid")) { + if (t_jsonObject.at("uid").is_uint64()) { localProperties.uid = t_jsonObject.at("uid").get_uint64(); } + else if (t_jsonObject.at("uid").is_int64()) { localProperties.uid = static_cast(t_jsonObject.at("uid").get_int64()); } + else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("area")) { - if (jsonObject["area"].isString()) { localProperties.location.area = jsonObject["area"].toString(); } + if (t_jsonObject.contains("area")) { + if (t_jsonObject.at("area").is_string()) { + localProperties.location.area = QString::fromUtf8(t_jsonObject.at("area").get_string().c_str()); + } else { jsonError = true; } } else if (gta5view_isGTAVFormat(format)) { jsonIncomplete = true; } - if (jsonObject.contains("crewid")) { - bool crewIDOk; - localProperties.crewID = jsonMap["crewid"].toInt(&crewIDOk); - if (!crewIDOk) { jsonError = true; } + if (t_jsonObject.contains("crewid")) { + if (t_jsonObject.at("crewid").is_uint64()) { localProperties.crewID = t_jsonObject.at("crewid").get_uint64(); } + else if (t_jsonObject.at("crewid").is_int64()) { localProperties.crewID = static_cast(t_jsonObject.at("crewid").get_int64()); } + else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("street")) { - bool streetIDOk; - localProperties.streetID = jsonMap["street"].toInt(&streetIDOk); - if (!streetIDOk) { jsonError = true; } + if (t_jsonObject.contains("street")) { + if (t_jsonObject.at("street").is_uint64()) { localProperties.streetID = t_jsonObject.at("street").get_uint64(); } + else if (t_jsonObject.at("street").is_int64()) { localProperties.streetID = static_cast(t_jsonObject.at("street").get_int64()); } + else { jsonError = true; } } else if (gta5view_isGTAVFormat(format)) { jsonIncomplete = true; } - if (jsonObject.contains("creat")) { - bool timestampOk; - QDateTime createdTimestamp; - localProperties.createdTimestamp = jsonMap["creat"].toUInt(×tampOk); -#if QT_VERSION >= 0x060000 - createdTimestamp.setSecsSinceEpoch(localProperties.createdTimestamp); -#else - createdTimestamp.setTime_t(localProperties.createdTimestamp); -#endif - localProperties.createdDateTime = createdTimestamp; - if (!timestampOk) { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("plyrs")) { - if (jsonObject["plyrs"].isArray()) { localProperties.playersList = jsonMap["plyrs"].toStringList(); } - else { jsonError = true; } - } - // else { jsonIncomplete = true; } // 2016 Snapmatic pictures left out plyrs when none are captured, so don't force exists on that one - if (jsonObject.contains("meme")) { - if (jsonObject["meme"].isBool()) { localProperties.isMeme = jsonObject["meme"].toBool(); } + if (t_jsonObject.contains("creat")) { + if (t_jsonObject.at("creat").is_int64()) { + QDateTime createdTimestamp; + localProperties.createdTimestamp = t_jsonObject.at("creat").get_int64(); + createdTimestamp.setSecsSinceEpoch(localProperties.createdTimestamp); + localProperties.createdDateTime = createdTimestamp; + } + else if (t_jsonObject.at("creat").is_uint64()) { + QDateTime createdTimestamp; + localProperties.createdTimestamp = static_cast(t_jsonObject.at("creat").get_uint64()); + createdTimestamp.setSecsSinceEpoch(localProperties.createdTimestamp); + localProperties.createdDateTime = createdTimestamp; + } else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("mug")) { - if (jsonObject["mug"].isBool()) { localProperties.isMug = jsonObject["mug"].toBool(); } + if (t_jsonObject.contains("plyrs")) { + if (t_jsonObject.at("plyrs").is_array()) { + boost::json::array plyrsArray = t_jsonObject.at("plyrs").get_array(); + QStringList playersList; + for (const boost::json::value &plyrVal : plyrsArray) { + if (plyrVal.is_string()) { + playersList << QString::fromUtf8(plyrVal.get_string().c_str()); + } + } + localProperties.playersList = playersList; + } + else { jsonError = true; } + } + if (t_jsonObject.contains("meme")) { + if (t_jsonObject.at("meme").is_bool()) { localProperties.isMeme = t_jsonObject.at("meme").get_bool(); } else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("slf")) { - if (jsonObject["slf"].isBool()) { localProperties.isSelfie = jsonObject["slf"].toBool(); } + if (t_jsonObject.contains("mug")) { + if (t_jsonObject.at("mug").is_bool()) { localProperties.isMug = t_jsonObject.at("mug").get_bool(); } else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("drctr")) { - if (jsonObject["drctr"].isBool()) { localProperties.isFromDirector = jsonObject["drctr"].toBool(); } + if (t_jsonObject.contains("slf")) { + if (t_jsonObject.at("slf").is_bool()) { localProperties.isSelfie = t_jsonObject.at("slf").get_bool(); } else { jsonError = true; } } else { jsonIncomplete = true; } - if (jsonObject.contains("rsedtr")) { - if (jsonObject["rsedtr"].isBool()) { localProperties.isFromRSEditor = jsonObject["rsedtr"].toBool(); } + if (t_jsonObject.contains("drctr")) { + if (t_jsonObject.at("drctr").is_bool()) { localProperties.isFromDirector = t_jsonObject.at("drctr").get_bool(); } + else { jsonError = true; } + } + else { jsonIncomplete = true; } + if (t_jsonObject.contains("rsedtr")) { + if (t_jsonObject.at("rsedtr").is_bool()) { localProperties.isFromRSEditor = t_jsonObject.at("rsedtr").get_bool(); } else { jsonError = true; } } else { localProperties.isFromRSEditor = false; } - if (jsonObject.contains("onislandx")) { - if (jsonObject["onislandx"].isBool()) { localProperties.location.isCayoPerico = jsonObject["onislandx"].toBool(); } + if (t_jsonObject.contains("onislandx")) { + if (t_jsonObject.at("onislandx").is_bool()) { localProperties.location.isCayoPerico = t_jsonObject.at("onislandx").get_bool(); } else { jsonError = true; } } else { localProperties.location.isCayoPerico = false; } @@ -992,46 +1016,59 @@ void SnapmaticPicture::parseJsonContent() bool SnapmaticPicture::setSnapmaticProperties(SnapmaticProperties properties) { - QJsonObject t_jsonObject = jsonObject; + boost::json::object t_jsonObject = snapmaticJson.jsonObject; - QJsonObject locObject; + boost::json::object locObject; locObject["x"] = properties.location.x; locObject["y"] = properties.location.y; locObject["z"] = properties.location.z; + boost::json::array plyrsArray; + for (const QString &player : properties.playersList) { + plyrsArray.push_back(player.toUtf8().constData()); + } + t_jsonObject["loc"] = locObject; t_jsonObject["uid"] = properties.uid; t_jsonObject["crewid"] = properties.crewID; - t_jsonObject["creat"] = QJsonValue::fromVariant(properties.createdTimestamp); - t_jsonObject["plyrs"] = QJsonValue::fromVariant(properties.playersList); + t_jsonObject["creat"] = properties.createdTimestamp; + t_jsonObject["plyrs"] = plyrsArray; t_jsonObject["meme"] = properties.isMeme; t_jsonObject["mug"] = properties.isMug; t_jsonObject["slf"] = properties.isSelfie; t_jsonObject["drctr"] = properties.isFromDirector; t_jsonObject["rsedtr"] = properties.isFromRSEditor; if (gta5view_isGTAVFormat(p_ragePhoto.format())) { - t_jsonObject["area"] = properties.location.area; + t_jsonObject["area"] = properties.location.area.toUtf8().constData(); t_jsonObject["street"] = properties.streetID; t_jsonObject["onislandx"] = properties.location.isCayoPerico; } - const QJsonDocument jsonDocument(t_jsonObject); - if (setJsonStr(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact)))) { + const std::string json = SnapmaticJson::serialize(t_jsonObject); + if (setJsonStr(QString::fromUtf8(json.c_str(), json.size()))) { localProperties = properties; return true; } return false; } -bool SnapmaticPicture::setJsonStr(const QString &newJsonStr, bool updateProperties) +bool SnapmaticPicture::setJsonStr(const QString &json, bool updateProperties) { - const QJsonDocument t_jsonDocument = QJsonDocument::fromJson(newJsonStr.toStdString().c_str()); - if (t_jsonDocument.isNull()) - return false; - const QByteArray t_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact); - jsonObject = t_jsonDocument.object(); + return setJsonStr(json.toStdString(), updateProperties); +} - p_ragePhoto.setJson(t_jsonData.constData()); +bool SnapmaticPicture::setJsonStr(const std::string &json, bool updateProperties) +{ + std::error_code ec; + const boost::json::value t_jsonValue = boost::json::parse(json, ec); + if (ec) + return false; + if (!t_jsonValue.is_object()) + return false; + const std::string t_json = SnapmaticJson::serialize(t_jsonValue); + snapmaticJson.jsonObject = t_jsonValue.get_object(); + + p_ragePhoto.setJson(t_json.c_str()); if (updateProperties) parseJsonContent(); return true; diff --git a/src/SnapmaticPicture.h b/src/SnapmaticPicture.h index e40689c..2d24d00 100644 --- a/src/SnapmaticPicture.h +++ b/src/SnapmaticPicture.h @@ -19,6 +19,7 @@ #ifndef SNAPMATICPICTURE_H #define SNAPMATICPICTURE_H +#include "SnapmaticJson.h" #ifdef RAGEPHOTO_USE_ABI_WRAPPER #include typedef RagePhotoA RagePhoto; @@ -26,7 +27,6 @@ typedef RagePhotoA RagePhoto; #include #endif #include -#include #include #include #include @@ -52,11 +52,11 @@ struct SnapmaticProperties { double z; bool isCayoPerico; }; - int uid; - int crewID; - int streetID; + uint64_t uid; + uint64_t crewID; + uint64_t streetID; QStringList playersList; - uint createdTimestamp; + int64_t createdTimestamp; QDateTime createdDateTime; bool isMeme; bool isMug; @@ -105,9 +105,11 @@ public: // JSON bool isJsonOk(); const QString getJsonStr(); + const std::string getJsonStdStr(); SnapmaticProperties getSnapmaticProperties(); bool setSnapmaticProperties(SnapmaticProperties properties); - bool setJsonStr(const QString &jsonStr, bool updateProperties = false); + bool setJsonStr(const std::string &json, bool updateProperties = false); + bool setJsonStr(const QString &json, bool updateProperties = false); // VISIBILITY bool isHidden(); @@ -116,12 +118,11 @@ public: bool setPictureVisible(); // ALTERNATIVES (MORE DEVELOPER FRIENDLY FUNCTION CALLS) - inline QString getJsonString() { return getJsonStr(); } inline QString getPictureJson() { return getJsonStr(); } inline QString getPictureTitle() { return getPictureTitl(); } inline uint32_t getPictureSize() { return ragePhoto()->jpegSize(); } inline QString getPictureString() { return getPictureStr(); } - inline bool setJsonString(const QString &jsonString, bool updateProperties = false) { return setJsonStr(jsonString, updateProperties); } // Please use setPictureJson instead + inline bool setPictureJson(const std::string &json, bool updateProperties = false) { return setJsonStr(json, updateProperties); } inline bool setPictureJson(const QString &json, bool updateProperties = false) { return setJsonStr(json, updateProperties); } inline bool setPictureTitle(const QString &title) { return setPictureTitl(title); } inline void setPictureFileName(const QString &fileName) { return setPicFileName(fileName); } @@ -169,7 +170,7 @@ private: void parseJsonContent(); bool jsonOk; SnapmaticProperties localProperties; - QJsonObject jsonObject; + SnapmaticJson snapmaticJson; // VERIFY CONTENT static bool verifyTitleChar(const QChar &titleChar); @@ -182,8 +183,6 @@ signals: void preloaded(); void updated(); void loaded(); - -public slots: }; #endif // SNAPMATICPICTURE_H diff --git a/src/json b/src/json new file mode 160000 index 0000000..31b10c1 --- /dev/null +++ b/src/json @@ -0,0 +1 @@ +Subproject commit 31b10c1b70556dfee414ef12f83d85e7d6443508 diff --git a/src/libragephoto b/src/libragephoto index cac7fd2..302be66 160000 --- a/src/libragephoto +++ b/src/libragephoto @@ -1 +1 @@ -Subproject commit cac7fd221f08a11e984d9b47b4383af548b388aa +Subproject commit 302be665e2bdd6fb00628ad6310b161dcf8c834d