Program Listing for File IRI.cpp¶
↰ Return to documentation for file (src/rdf4cpp/IRI.cpp)
#include "IRI.hpp"
#include <rdf4cpp/IRIView.hpp>
#include <rdf4cpp/InvalidNode.hpp>
#include <rdf4cpp/writer/TryWrite.hpp>
#include <sstream>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
namespace rdf4cpp {
IRI::IRI(storage::identifier::NodeBackendHandle handle) noexcept : Node(handle) {
}
IRI::IRI() noexcept : Node{storage::identifier::NodeBackendHandle{}} {
}
IRI::IRI(std::string_view iri, storage::DynNodeStoragePtr node_storage)
: IRI{make_unchecked((validate(iri), iri), node_storage)} {
}
IRI::IRI(datatypes::registry::DatatypeIDView id, storage::DynNodeStoragePtr node_storage) noexcept
: IRI{visit(datatypes::registry::DatatypeIDVisitor{
[&](storage::identifier::LiteralType const fixed) -> IRI {
return IRI{storage::identifier::NodeBackendHandle{storage::identifier::literal_type_to_iri_node_id(fixed),
node_storage}};
},
[&](std::string_view const dynamic) -> IRI {
return IRI::make_unchecked(dynamic, node_storage);
}},
id)} {
}
IRI IRI::make_null() noexcept {
return IRI{};
}
IRI IRI::make(std::string_view iri, storage::DynNodeStoragePtr node_storage) {
return IRI{iri, node_storage};
}
IRI IRI::make_unchecked(std::string_view iri, storage::DynNodeStoragePtr node_storage) {
return IRI{storage::identifier::NodeBackendHandle{node_storage.find_or_make_id(storage::view::IRIBackendView{.identifier = iri}),
node_storage}};
}
IRI IRI::make_uuid(storage::DynNodeStoragePtr node_storage) {
boost::uuids::random_generator_mt19937 gen{};
boost::uuids::uuid u = gen();
std::stringstream stream{};
stream << "urn:uuid:" << u;
return IRI{stream.view(), node_storage};
}
void IRI::validate(std::string_view s) {
auto v = IRIView(s).quick_validate();
if (v != IRIFactoryError::Ok)
throw InvalidNode(std::format("IRI {} is invalid: {}", s, v));
}
IRI IRI::to_node_storage(storage::DynNodeStoragePtr node_storage) const {
if (handle_.storage() == node_storage || null()) {
return *this;
}
auto const node_id = node_storage.find_or_make_id(handle_.iri_backend());
return IRI{storage::identifier::NodeBackendHandle{node_id, node_storage}};
}
IRI IRI::try_get_in_node_storage(storage::DynNodeStoragePtr node_storage) const noexcept {
if (handle_.storage() == node_storage || null()) {
return *this;
}
auto const node_id = node_storage.find_id(handle_.iri_backend());
if (node_id.null()) {
return IRI{};
}
return IRI{storage::identifier::NodeBackendHandle{node_id, node_storage}};
}
IRI IRI::find(std::string_view iri, storage::DynNodeStoragePtr node_storage) noexcept {
auto nid = node_storage.find_id(storage::view::IRIBackendView{iri});
if (nid.null())
return IRI{};
return IRI{storage::identifier::NodeBackendHandle{nid, node_storage}};
}
IRI IRI::find(datatypes::registry::DatatypeIDView id, storage::DynNodeStoragePtr node_storage) noexcept {
return visit(datatypes::registry::DatatypeIDVisitor{
[&](storage::identifier::LiteralType const fixed) -> IRI {
return IRI{storage::identifier::NodeBackendHandle{storage::identifier::literal_type_to_iri_node_id(fixed),
node_storage}};
},
[&](std::string_view const dynamic) -> IRI {
return IRI::find(dynamic, node_storage);
}},
id);
}
IRI::operator datatypes::registry::DatatypeIDView() const noexcept {
using namespace storage::identifier;
auto const id = this->handle_.id();
LiteralType const type = iri_node_id_to_literal_type(id);
if (type.is_fixed()) {
return datatypes::registry::DatatypeIDView{type};
} else {
return datatypes::registry::DatatypeIDView{this->identifier()};
}
}
bool IRI::serialize(writer::BufWriterParts const writer) const noexcept {
if (null()) {
return rdf4cpp::writer::write_str("null", writer);
}
auto const backend = handle_.iri_backend();
RDF4CPP_DETAIL_TRY_WRITE_STR("<");
RDF4CPP_DETAIL_TRY_WRITE_STR(backend.identifier);
RDF4CPP_DETAIL_TRY_WRITE_STR(">");
return true;
}
IRI::operator std::string() const noexcept {
return writer::StringWriter::oneshot([this](auto &w) noexcept {
return this->serialize(w);
});
}
IRI IRI::default_graph(storage::DynNodeStoragePtr node_storage) {
namespace reg = datatypes::registry;
namespace sid = storage::identifier;
auto const id = reg::reserved_datatype_ids[reg::default_graph_iri];
return IRI{sid::NodeBackendHandle{sid::literal_type_to_iri_node_id(id),
node_storage}};
}
TriBool IRI::is_default_graph() const noexcept {
namespace reg = datatypes::registry;
namespace sid = storage::identifier;
if (null()) {
return TriBool::Err;
}
auto const expected_id = reg::reserved_datatype_ids[reg::default_graph_iri];
auto const this_id = sid::iri_node_id_to_literal_type(backend_handle().id());
return this_id == expected_id;
}
IRI IRI::rdf_type(storage::DynNodeStoragePtr node_storage) {
namespace reg = datatypes::registry;
namespace sid = storage::identifier;
auto const id = reg::reserved_datatype_ids[reg::rdf_type];
return IRI{sid::NodeBackendHandle{sid::literal_type_to_iri_node_id(id),
node_storage}};
}
TriBool IRI::is_rdf_type() const noexcept {
namespace reg = datatypes::registry;
namespace sid = storage::identifier;
if (null()) {
return TriBool::Err;
}
auto const expected_id = reg::reserved_datatype_ids[reg::rdf_type];
auto const this_id = sid::iri_node_id_to_literal_type(backend_handle().id());
return this_id == expected_id;
}
std::ostream &operator<<(std::ostream &os, IRI const &iri) {
writer::BufOStreamWriter w{os};
iri.serialize(w);
w.finalize();
return os;
}
std::string_view IRI::identifier() const noexcept {
return handle_.iri_backend().identifier;
}
FetchOrSerializeResult IRI::fetch_or_serialize_identifier(std::string_view &out, [[maybe_unused]] writer::BufWriterParts writer) const noexcept {
auto const id = identifier();
out = id;
return FetchOrSerializeResult::Fetched;
}
inline namespace shorthands {
IRI operator""_iri(char const *str, size_t const len) {
return IRI{std::string_view{str, len}};
}
} // namespace shorthands
} // namespace rdf4cpp
auto std::formatter<rdf4cpp::IRI>::format(rdf4cpp::IRI n, format_context &ctx) const -> decltype(ctx.out()) {
rdf4cpp::writer::BufOutputIteratorWriter w{ctx.out()};
n.serialize(w);
w.finalize();
return w.buffer().iter;
}