replace json serializer with boost, libragephoto upstream
This commit is contained in:
		
							parent
							
								
									aa4b2fc080
								
							
						
					
					
						commit
						557b999608
					
				
					 10 changed files with 308 additions and 104 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
#include "JsonEditorDialog.h"
 | 
			
		||||
#include "ui_JsonEditorDialog.h"
 | 
			
		||||
#include "SnapmaticEditor.h"
 | 
			
		||||
#include "SnapmaticJson.h"
 | 
			
		||||
#include "AppEnv.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <QStringBuilder>
 | 
			
		||||
| 
						 | 
				
			
			@ -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("<h4>Unsaved changes detected</h4>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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ signals:
 | 
			
		|||
    void codeUpdated(QString jsonCode);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString jsonCode;
 | 
			
		||||
    std::string jsonCode;
 | 
			
		||||
    JSHighlighter *jsonHl;
 | 
			
		||||
    SnapmaticPicture *smpic;
 | 
			
		||||
    Ui::JsonEditorDialog *ui;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										123
									
								
								src/SnapmaticJson.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/SnapmaticJson.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <boost/json/src.hpp>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								src/SnapmaticJson.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/SnapmaticJson.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef SNAPMATICJSON_H
 | 
			
		||||
#define SNAPMATICJSON_H
 | 
			
		||||
#ifndef Q_MOC_RUN
 | 
			
		||||
 | 
			
		||||
#include <boost/json.hpp>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -18,8 +18,6 @@
 | 
			
		|||
 | 
			
		||||
#include "SnapmaticPicture.h"
 | 
			
		||||
#include <QStringBuilder>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
#include <QStringList>
 | 
			
		||||
#include <QVariantMap>
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
| 
						 | 
				
			
			@ -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<double>(locObject.at("x").get_int64()); }
 | 
			
		||||
                else if (locObject.at("x").is_uint64()) { localProperties.location.x = static_cast<double>(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<double>(locObject.at("y").get_int64()); }
 | 
			
		||||
                else if (locObject.at("y").is_uint64()) { localProperties.location.x = static_cast<double>(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<double>(locObject.at("z").get_int64()); }
 | 
			
		||||
                else if (locObject.at("z").is_uint64()) { localProperties.location.x = static_cast<double>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<int64_t>(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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
#ifndef SNAPMATICPICTURE_H
 | 
			
		||||
#define SNAPMATICPICTURE_H
 | 
			
		||||
 | 
			
		||||
#include "SnapmaticJson.h"
 | 
			
		||||
#ifdef RAGEPHOTO_USE_ABI_WRAPPER
 | 
			
		||||
#include <RagePhotoA.h>
 | 
			
		||||
typedef RagePhotoA RagePhoto;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +27,6 @@ typedef RagePhotoA RagePhoto;
 | 
			
		|||
#include <RagePhoto.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <QStringList>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QString>
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								src/json
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								src/json
									
										
									
									
									
										Submodule
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Subproject commit 31b10c1b70556dfee414ef12f83d85e7d6443508
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit cac7fd221f08a11e984d9b47b4383af548b388aa
 | 
			
		||||
Subproject commit 302be665e2bdd6fb00628ad6310b161dcf8c834d
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue