User Tools

Site Tools


wiki:qjsondocument_conversions_serialisation_qfile_qjsonvalue_operator_conversions

QJson/Qt/C++ QJsonDocument, QJsonValue, QFile, conversion, operator overloading & notes

conversion to/from QJsonValues with operator & ctor

this uses operator overloading and ctor overload to convert formats. it seems reasonable.

struct Custom {
 
    Custom() { }
    Custom(const Custom & _src) = default;
 
    // note; you can knuckle down here and insist on specialisation of QJV and only
    // allow a QJA. that would make the caller double check, not a bad thing
    // see note below about QJsonContainer
    Custom(const QJsonValue & _) {
        QJsonArray ja = _.toArray();
        if (ja != QJsonArray()) {
            for (int i = 0; i < 4; i++) {
                special_data[i] = ja.at(i).toInt(0);
            }
        }
    }
 
    // it's not symmetrical at all
    operator QJsonValue() const {
        return QJsonArray{
            special_data[0],
            special_data[1],
            special_data[2],
            special_data[3]};
    }
 
    // output this as javascript… yes… output this…… as javascript………
    union {
        float normal_data;
        char special_data[4];
        unsigned short empty_data[2];
    };
};

notes

most other implementations (game read/write 4xmpl) implement read/write functions all the way down the object tree. this approach seems interesting as chaining (treeing) the output reads very nicely. see below. placing the JSON read in the ctor means a default value is available if anything inside fails nad error can be returned with a simple error state variable

adding custom data to Json objects

    Custom custom;
    custom.normal_data = 3.141592653f;
 
    QJsonObject jo;
    jo.insert("_data_version", "1");
    jo.insert("_data", custom);

adding custom data to Json arrays

    // make some data up
    Custom custom_array[3];
    custom_array[0].normal_data = 1.0;
    custom_array[1].normal_data = -1.0;
    custom_array[2].normal_data = 0.0;
 
    // use QJsonArray initializer lists
    QJsonArray ja { custom_array[0], custom_array[1], custom_array[2] };

converting/reading/writing to/from QFile and QJsonDocument

these utility functions convert a file to/from JSON format using Qt

QJsonObject and QJsonArray are accepted/returned by the QJsonDocument de/serializer. cowever, should they both derive from a common “QJsonContainer” then no distinction would need to be made concluding this would be that QJsonContainer is readily converted to a QJsonValue. That is a QJsonValue can take a QJsonContainer (it can already take QJsonObject and QJsonArray)

they convert to a QJsonValue rather than an object or array. failure is indicated by a null value. first see comments about a QJsonContainer class above then return here. 'fromFile' indicates failure by returning the JSON 'null' value. this value is not valid at the top level of a file, however, the toFile function also accepts a QJsonValue meaning null can be pass in. toFile should only accept a QJsonContainer

read

QJsonValue fromFile(const QString & _path) {
    QFile file(_path);
    if (file.open(QIODevice::ReadOnly)) {
        // interesting, can't cast up
        // that is QJsonDocument -> QJsonValue is impossible
        // however, i bet there is a single json value inside the doc
        QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
        // what's the top level? just want to return a value (spec is nothing here)
        // what's the problem with assiging a json doc to a json value?
 
        if (doc.isArray()) {
            return QJsonValue(doc.array());
        }
        else if (doc.isObject()) {
            return QJsonValue(doc.object());
        }
        else if (doc.isNull()) {
            return QJsonValue();
        }
        else if (doc.isEmpty()) {
            return QJsonValue();
        }
    }
    return QJsonValue();
}

write

bool toFile(const QJsonValue & _src, const QString & _path) {
    QFile file(_path);
    if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        // again with the conversion, maybe i should care, i don't
        QJsonDocument doc;
        if (_src.isArray()) {
            doc.setArray(_src.toArray());
            file.write(doc.toJson());
            return true;
        }
        else if (_src.isObject()) {
            doc.setObject(_src.toObject());
            file.write(doc.toJson());
            return true;
        }
    }
    return false;
}

additional notes (empty)

wiki/qjsondocument_conversions_serialisation_qfile_qjsonvalue_operator_conversions.txt · Last modified: 2016/11/22 09:27 by xylene