-
Cyrille Berger authoredCyrille Berger authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ValueHash.cpp 6.38 KiB
#include "ValueHash.h"
#include <QCryptographicHash>
#include <QJsonArray>
#include <QJsonObject>
#include <QCborArray>
#include <QCborMap>
using namespace knowCore;
struct ValueHash::Private : public QSharedData
{
QHash<QString, Value> values;
};
ValueHash::ValueHash() : d(new Private)
{
}
ValueHash::ValueHash(std::initializer_list<std::pair<QString, Value> > _list) : ValueHash(QHash<QString, Value>(_list))
{
}
ValueHash::ValueHash(const QHash<QString, Value>& _values) : d(new Private)
{
d->values = _values;
}
ValueHash::ValueHash(const ValueHash& _rhs) : d(_rhs.d)
{
}
ValueHash ValueHash::operator=(const ValueHash& _rhs)
{
d = _rhs.d;
return *this;
}
ValueHash::~ValueHash()
{
}
int ValueHash::size() const
{
return d->values.size();
}
Value ValueHash::value(const QString& _key) const
{
return d->values.value(_key);
}
bool ValueHash::contains(const QString& _key) const
{
return d->values.contains(_key);
}
bool ValueHash::operator==(const ValueHash& _rhs) const
{
return d->values == _rhs.d->values;
}
bool ValueHash::operator==(const QHash<QString, Value>& _rhs) const
{
return d->values == _rhs;
}
ReturnValue<QByteArray> ValueHash::md5() const
{
QCryptographicHash hash(QCryptographicHash::Md5);
for(const Value& value : d->values)
{
KNOWCORE_RETURN_VALUE_TRY(value_md5, value.md5());
hash.addData(value_md5);
}
return kCrvSuccess(hash.result());
}
#define DATATYPE_KEY u8"datatype"_kCs
#define KEY_KEY u8"key"_kCs
#define VALUE_KEY u8"value"_kCs
ReturnValue<QJsonValue> ValueHash::toJsonValue(const SerialisationContexts& _contexts) const
{
QJsonArray array;
for(auto it = d->values.begin(); it != d->values.end(); ++it)
{
KNOWCORE_RETURN_VALUE_TRY(value_json, it.value().toJsonValue(_contexts));
QJsonObject object;
object[KEY_KEY] = it.key();
object[DATATYPE_KEY] = (QString)it.value().datatype();
object[VALUE_KEY] = value_json;
array.append(object);
}
return kCrvSuccess(array);
}
ReturnValue<ValueHash> ValueHash::fromJsonValue(const QJsonValue& _json_value, const DeserialisationContexts& _context)
{
if(_json_value.isArray())
{
QHash<QString, Value> values;
QJsonArray json_array = _json_value.toArray();
for(int i = 0; i < json_array.size(); ++i)
{
QJsonValue json_value = json_array.at(i);
if(json_value.isObject())
{
QJsonObject obj = json_value.toObject();
Uri datatype = obj.value(DATATYPE_KEY).toString();
KNOWCORE_RETURN_VALUE_TRY(value, Value::fromJsonValue(datatype, obj.value(VALUE_KEY), _context));
values[obj.value(KEY_KEY).toString()] = value;
} else {
return kCrvError("Expected object got '{}' when parsing ValueHash '{}'", json_value, _json_value);
}
}
return kCrvSuccess(values);
} else {
return kCrvError("Expect array got '{}'", _json_value);
}
}
ReturnValue<QCborValue> ValueHash::toCborValue(const SerialisationContexts& _contexts) const
{
QCborArray array;
for(auto it = d->values.begin(); it != d->values.end(); ++it)
{
KNOWCORE_RETURN_VALUE_TRY(value_cbor, it.value().toCborValue(_contexts));
QCborMap map;
map[KEY_KEY] = it.key();
map[DATATYPE_KEY] = (QString)it.value().datatype();
map[VALUE_KEY] = value_cbor;
array.append(map);
}
return kCrvSuccess(array);
}
ReturnValue<ValueHash> ValueHash::fromCborValue(const QCborValue& _cbor_value, const DeserialisationContexts& _contexts)
{
if(_cbor_value.isArray())
{
QHash<QString, Value> values;
QCborArray cbor_array = _cbor_value.toArray();
for(int i = 0; i < cbor_array.size(); ++i)
{
QCborValue cbor_value = cbor_array.at(i);
if(cbor_value.isMap())
{
QCborMap obj = cbor_value.toMap();
Uri datatype = obj.value(DATATYPE_KEY).toString();
KNOWCORE_RETURN_VALUE_TRY(value, Value::fromCborValue(datatype, obj.value(VALUE_KEY), _contexts));
values[obj.value(KEY_KEY).toString()] = value;
} else {
return kCrvError("Expected object got '{}' when parsing ValueHash '{}'", cbor_value, _cbor_value);
}
}
return kCrvSuccess(values);
} else {
return kCrvError("Expect array got '{}'", _cbor_value);
}
}
ReturnValue<QString> ValueHash::printable() const
{
QStringList strings;
for(const Value& v : d->values)
{
KNOWCORE_RETURN_VALUE_TRY(str, v.printable());
strings.append(str);
}
return kCrvSuccess(clog_qt::qformat("[{}]", ", "));
}
QHash<QString, Value> ValueHash::hash() const
{
return d->values;
}
ReturnValue<void> ValueHash::checkContainsOnly(const knowCore::Uri& _uri) const
{
for(const Value& value : d->values)
{
if(value.datatype() != _uri)
{
return kCrvError("Invalid type '{}' in list, expected: '{}'", value.datatype(), _uri);
}
}
return kCrvSuccess();
}
#include <knowCore/Uris/askcore_types.h>
#include "MetaTypeImplementation.h"
KNOWCORE_DEFINE_METATYPE_START_IMPLEMENTATION(ValueHash)
ReturnValue<QByteArray> md5(const ValueHash& _value) const override
{
return _value.md5();
}
ReturnValue<QJsonValue> toJsonValue(const ValueHash& _value, const SerialisationContexts& _contexts) const override
{
return _value.toJsonValue(_contexts);
}
ReturnValue<void> fromJsonValue(ValueHash* _value, const QJsonValue& _json_value, const DeserialisationContexts& _contexts) const override
{
return kCrvTryAssign(_value, ValueHash::fromJsonValue(_json_value, _contexts));
}
ReturnValue<QCborValue> toCborValue(const ValueHash& _value, const SerialisationContexts& _contexts) const override
{
return _value.toCborValue(_contexts);
}
ReturnValue<void> fromCborValue(ValueHash* _value, const QCborValue& _cbor_value, const DeserialisationContexts& _contexts) const override
{
return kCrvTryAssign(_value, ValueHash::fromCborValue(_cbor_value, _contexts));
}
ReturnValue<QString> printable(const ValueHash& _value) const override
{
return _value.printable();
}
ReturnValue<QString> toRdfLiteral(const ValueHash& _value, const SerialisationContexts& _contexts) const override
{
return toJsonString(_value, _contexts);
}
ReturnValue<void> fromRdfLiteral(ValueHash* _value, const QString& _serialised, const DeserialisationContexts& _contexts) const override
{
return fromJsonString(_value, _serialised, _contexts);
}
KNOWCORE_DEFINE_METATYPE_FINISH_IMPLEMENTATION(ValueHash)
KNOWCORE_DEFINE_METATYPE(ValueHash, Uris::askcore_types::valuehash, MetaTypeTraits::None)