9#include <QCryptographicHash>
14bool Rdf::Term::operator<(
const Rdf::Term& other)
const
16 if (type == other.type) {
17 if (value == other.value) {
18 return literalType < other.literalType;
20 return value < other.value;
22 return type < other.type;
25bool Rdf::Term::operator==(
const Rdf::Term& other)
const
27 return type == other.type && value == other.value && literalType == other.literalType;
30bool Rdf::Quad::operator<(
const Rdf::Quad &other)
const
32 if (subject == other.subject) {
33 if (predicate == other.predicate) {
34 return object < other.object;
36 return predicate < other.predicate;
38 return subject < other.subject;
42static QByteArray hashFirstDegreeQuads(
const std::vector<Rdf::Quad> &quads,
const QString &refBlankNode)
44 const auto renameBlankNode = [&refBlankNode](Rdf::Term &term) {
45 if (term.type == Rdf::Term::BlankNode) {
46 if (term.value == refBlankNode) {
47 term.value = QStringLiteral(
"a");
49 term.value = QStringLiteral(
"z");
54 std::vector<Rdf::Quad> toHash;
55 for (
auto quad : quads) {
56 renameBlankNode(quad.subject);
57 renameBlankNode(quad.predicate);
58 renameBlankNode(quad.object);
59 toHash.push_back(std::move(quad));
62 std::sort(toHash.begin(), toHash.end());
66QByteArray Rdf::serialize(
const std::vector<Rdf::Quad>& quads)
71 Rdf::serialize(&buffer, quads);
76void Rdf::normalize(std::vector<Rdf::Quad>& quads)
80 for (
const auto &quad : quads) {
82 if (quad.subject.type == Rdf::Term::BlankNode) {
83 blankNodeToQuadMap[quad.subject.value].push_back(quad);
85 if (quad.object.type == Rdf::Term::BlankNode) {
86 blankNodeToQuadMap[quad.object.value].push_back(quad);
91 for (
auto it = blankNodeToQuadMap.
begin(); it != blankNodeToQuadMap.
end(); ++it) {
92 hashToBlankNodeMap.
insert(hashFirstDegreeQuads(it.value(), it.key()), it.key());
95 int c14nIdCounter = 0;
97 for (
auto it = hashToBlankNodeMap.
begin(); it != hashToBlankNodeMap.
end(); ++it) {
101 const auto translateBlankNode = [&blankNodeC14nMap](Rdf::Term &term) {
102 if (term.type == Rdf::Term::BlankNode) {
103 const auto it = blankNodeC14nMap.
constFind(term.value);
104 if (it != blankNodeC14nMap.
constEnd()) {
105 term.value = it.value();
109 for (
auto &quad : quads) {
110 translateBlankNode(quad.subject);
111 translateBlankNode(quad.predicate);
112 translateBlankNode(quad.object);
115 std::sort(quads.begin(), quads.end());
116 quads.erase(std::unique(quads.begin(), quads.end(), [](
const auto &lhs,
const auto &rhs) {
117 return lhs.subject == rhs.subject && lhs.predicate == rhs.predicate && lhs.object == rhs.object;
121void Rdf::serialize(
QIODevice *out,
const std::vector<Rdf::Quad> &quads)
123 for (
const auto &quad : quads) {
124 serialize(out, quad);
128void Rdf::serialize(
QIODevice *out,
const Rdf::Quad &quad)
130 serialize(out, quad.subject);
132 serialize(out, quad.predicate);
134 serialize(out, quad.object);
138void Rdf::serialize(
QIODevice* out,
const Rdf::Term &term)
143 out->
write(term.value.toUtf8());
146 case Term::BlankNode:
148 out->
write(term.value.toUtf8());
152 out->
write(term.value.toUtf8());
154 if (!term.literalType.isEmpty()) {
156 out->
write(term.literalType.toUtf8());
160 case Term::Undefined:
161 out->
write(term.value.toUtf8());
Type type(const QSqlDatabase &db)
QByteArray toHex(char separator) const const
QByteArray hash(QByteArrayView data, Algorithm method)
const_iterator constEnd() const const
const_iterator constFind(const Key &key) const const
iterator insert(const Key &key, const T &value)
qint64 write(const QByteArray &data)
iterator insert(const Key &key, const T &value)
QString number(double n, char format, int precision)