Serd

Serd is a lightweight C library for working with RDF data in Turtle, NTriples, NQuads, and TriG formats.

This is the documentation for its C++ bindings, a thin header-only wrapper that provides more convenience and safety, with minimal overhead compared to using the C API directly.

Using Serd

The serd C++ API is declared in serd.hpp:

#include <serd/serd.hpp>

This header declares several kinds of object that can be used together in various ways, depending on the needs of the application.

The World represents an instance of serd, and is used to manage “global” facilities like logging.

A Node is the basic building block of data, 3 or 4 nodes together make a Statement.

Objects stream data to each other via Sink, which is an abstract interface that receives Events. Several objects act as a sink, which allow them to be combined into custom pipelines for processing data. For example, a Canon converts literals to canonical form, and a Filter filters statements that match (or do not match) some pattern.

The syntactic context at a particular point is represented by an Environment. This stores the base URI and set of namespace prefixes, which are used to expand relative URIs and abbreviated nodes.

Reading and writing data is performed using a Reader, which reads text and emits data to a sink, and a Writer, which is a sink that writes the incoming data as text. Both work in a streaming fashion so that large documents can be pretty-printed, translated, or otherwise processed quickly using only a small amount of memory.

A set of statements can be stored in memory as a Model. A model can be configured with various indices to provide good performance for different searches. A model acts as a collection of statements, with an Iterator that points to a statement, and a Range that points to a range of statements. It also provides several special query methods, which allow searching for statements in logarigthmic time assuming the appropriate indices are enabled.

Data can be loaded into a model via an Inserter, which is a sink that inserts incoming statements into a model. A range of the model (possibly the entire model) can later be written out by calling its write method with a writer.

For example, a simple pipeline to read a document, filter out some statements, and write the result to a new file, would look something like:

_images/writer_pipeline.svg

Here, event streams are shown as a dashed line, and a solid line represents explicit use of an object. In other words, dashed lines represent connections via the abstract Sink interface, and solid lines represent direct use of an object. In this case both reader and writer are using the same environment, so the output document will have the same abbreviations as the input. It is also possible to use different environments, for example to set additional namespace prefixes to further abbreviate the document.

Similarly, a document could be loaded into a model with canonical literals using a pipeline like:

_images/model_pipeline.svg

Many other useful pipelines are possible, and applications can implement custom sinks if those included with serd are not sufficient.

The remainder of this overview gives a brief bottom-up introduction to the API, with links to the complete reference where specific details can be found.

C++ Facilities

String Views

For performance reasons, most functions that take a string take a StringView. This allows many types of string to be passed as an argument, and redundant string measurement to be avoided.

StringView works similarly to std::string_view (and will likely be removed when C++17 support is more widespread). A StringView parameter will accept a string literal, dynamic C string, or a std::string as an argument. Note, however, that the constructor that takes only a const char* calls strlen to measure the string, so care should be taken to avoid this in performance-critical code if the string length is already known.

Optionals

Several places in the C API take or return a pointer that may be null. This is wrapped more safely in the C++ API as an Optional.

From a user perspective, Optional works similarly to std::optional, with pointer-like access operators and explicit boolean conversion enabling code like:

if (optional_value) {
  use_value(*optional_value);
}

or:

if (optional_object) {
  optional_object->do_something();
}

The Optional implementation is serd-specific, and takes advantage of the fact that the contained object is really just a “fancy pointer”. This means that null can be used to represent an unset value, avoiding the space overhead of more general types like std::optional.

A pointer to the underlying C object can be retrieved with the cobj() method, which will return null if the optional is unset.

Nodes

Nodes are the basic building blocks of data. Nodes are essentially strings, but also have a type, and optionally either a datatype or a language.

In RDF, a node is either a literal, URI, or blank. Serd can also represent “CURIE” nodes, or shortened URIs, which represent prefixed names often written in documents.

Fundamental Constructors

There are five fundamental node constructors which can be used to create any node:

make_plain_literal()

Creates a new string literal with an optional language tag.

make_typed_literal()

Creates a new string literal with a datatype URI.

make_blank()

Creates a new blank node ID.

make_curie()

Creates a new shortened URI.

make_uri()

Creates a new URI.

Convenience Constructors

For convenience, several other constructors are provided to make common types of nodes:

make_string()

Creates a new string literal (with no datatype or language).

make_file_uri()

Creates a new file URI from a path.

make_boolean()

Creates a new boolean literal.

make_decimal()

Creates a new decimal literal.

make_double()

Creates a new double literal.

make_float()

Creates a new float literal.

make_integer()

Creates a new integer literal.

make_base64()

Creates a new binary blob literal using xsd:base64Binary encoding.

The datatype or language, if present, can be retrieved with the datatype() or language() method, respectively. Note that no node has both a datatype and a language.

Statements

A Statement is a tuple of either 3 or 4 nodes: the subject, predicate, object, and optional graph. Statements declare that a subject has some property. The predicate identifies the property, and the object is its value on the subject.

A statement can be thought of as a very simple machine-readable sentence. The subject and object are as in natural language, and the predicate is something like a verb, but more general. For example, we could make a statement in English about your intrepid author:

drobilla has the first name “David”

We can break this statement into 3 pieces like so:

Subject

Predicate

Object

drobilla

has the first name

“David”

To make a Statement out of this, we need to define some URIs. In RDF, the subject and predicate must be resources with an identifier (for example, neither can be a string). Conventionally, predicate names do not start with “has” or similar words, since that would be redundant in this context. So, we assume that http://example.org/drobilla is the URI for drobilla, and that http://example.org/firstName has been defined somewhere to be a property with the appropriate meaning, and can make an equivalent Statement:

Statement triple{make_uri("http://example.org/drobilla"),  // Subject
                 make_uri("http://example.org/firstName"), // Predicate
                 make_string("David")};                    // Object

Statements also have an additional field, the graph, which is used to group statements together. For example, this can be used to store the document where statements originated, or to keep schema data separate from application data. A statement with a graph can be constructed by passing the graph as the fourth parameter:

Statement quad{make_uri("http://example.org/drobilla"),  // Subject
               make_uri("http://example.org/firstName"), // Predicate
               make_string("David"),                     // Object
               make_uri("http://example.org/userData")}; // Graph

Finally, a Cursor may also be passed which records a position in the file that the statement was loaded from. This is typically used for printing useful error messages. The cursor is considered metadata and not part of the statement itself, for example, it is not considered in equality comparison. Typically, the cursor will be automatically set by a reader, but a statement with a cursor can be constructed manually by passing the cursor as the last parameter:

Node      file{make_uri("file:///tmp/userdata.ttl")};
Statement triple2{make_uri("http://example.org/drobilla"),  // Subject
                  make_uri("http://example.org/firstName"), // Predicate
                  make_string("David"),                     // Object
                  Cursor{file, 4, 27}};                     // Cursor
Statement quad2{make_uri("http://example.org/drobilla"),  // Subject
                make_uri("http://example.org/firstName"), // Predicate
                make_string("David"),                     // Object
                make_uri("http://example.org/userData"),  // Graph
                Cursor{file, 4, 27}};                     // Cursor

Accessing Fields

Statement fields can be accessed with the node() method, for example:

NodeView s = statement.node(Field::subject);

Alternatively, an accessor function is provided for each field:

NodeView           p = statement.predicate();
NodeView           o = statement.object();
Optional<NodeView> g = statement.graph();

Every statement has a subject, predicate, and object, but the graph is optional. The cursor is also optional, and can be accessed with the cursor() method:

Optional<CursorView> c = statement.cursor();

Comparison

Two statements can be compared with the equals operator:

if (statement1 == statement2) {
  std::cout << "Match" << std::endl;
}

Statements are equal if all four corresponding pairs of nodes are equal. The cursor is considered metadata, and is ignored for comparison.

It is also possible to match statements against a pattern with the matches() method, where empty parameters act as wildcards:

if (statement.matches({}, make_uri("http://example.org/name"), {})) {
  std::cout << statement.subject() << " has name " << statement.object()
            << std::endl;
}

World

So far, we have only used nodes and statements, which are simple independent objects. Higher-level facilities in Serd require a World, which represents the global library state.

A program typically uses just one world, which can be constructed with no arguments:

World world;

All “global” library state is handled explicitly via the world. Serd does not contain any static mutable data, allowing it to be used concurrently in several parts of a program, for example in plugins.

If multiple worlds are used in a single program, they must never be mixed: objects “inside” one world can not be used with objects inside another.

Note that the world is not a database, it only manages a small amount of library state for things like configuration and logging.

Generating Blanks

Blank nodes, or simply “blanks”, are used for resources that do not have URIs. Unlike URIs, they are not global identifiers, and only have meaning within their local context (for example, a document). The world provides a method for automatically generating unique blank identifiers:

Node blank = world.get_blank();

Model

A Model is an indexed set of statements. A model can be used to store any set of data, from a few statements (for example, a protocol message), to an entire document, to a database with millions of statements.

Constructing a model requires a world, and flags which can be used to configure the model:

Model model{world, ModelFlag::index_SPO};

Combinations of flags can be used to enable different indices, or the storage of graphs and cursors. For example, to be able to quickly search by predicate, and store a cursor for each statement, the flags ModelFlag::index_PSO and ModelFlag::store_cursors could be added like so:

Model fancy_model{
  world,
  (ModelFlag::index_SPO | ModelFlag::index_PSO | ModelFlag::store_cursors)};

Model Operations

Models are value-like and can be copied and compared for equality:

Model copy{model};
assert(copy == model);

copy = fancy_model;
assert(copy == fancy_model);

The number of statements in a model can be accessed with the size() and empty() methods:

if (model.empty()) {
  std::cout << "Model is empty" << std::endl;
} else if (model.size() > 9000) {
  std::cout << "Model has over 9000 statements" << std::endl;
}

Destroying a model invalidates all nodes and statements within that model, so care should be taken to ensure that no dangling pointers are created.

Adding Statements

Statements can be added to the model by passing the nodes of the statement to insert():

Node s{make_uri("http://example.org/thing")};
Node p{make_uri("http://example.org/name")};
Node o{make_string("Thing")};

model.insert(s, p, o);

Alternatively, if you already have a statement (for example from another model), the overload that takes a StatementView can be used instead. For example, the first statement in one model could be added to another like so:

model.insert(*other_model.begin());

An entire range of statements can be inserted at once by passing a range. For example, all statements in one model could be copied into another like so:

model.insert(other_model.all());

Note that this overload consumes its argument, so a copy must be made to insert a range without modifying the original.

Iteration

An iterator is a reference to a particular statement in a model. The begin() method returns an iterator to the first statement in the model, and end() returns a sentinel that is one past the last statement in the model:

Iter i = model.begin();
if (i == model.end()) {
  std::cout << "Model is empty" << std::endl;
} else {
  std::cout << "First statement subject: " << i->subject() << std::endl;
}

Iterators can be advanced and compared manually:

if (++i != model.end()) {
  std::cout << "Second statement subject: " << i->subject() << std::endl;
}

However, they are more typically used automatically when iterating over a model:

for (const StatementView& statement : model) {
  std::cout << "Model statement subject: " << statement.subject()
            << std::endl;
}

Ranges

It is often more convenient to work with ranges of statements, rather than iterators to individual statements.

The simplest range, the range of all statements in the model, is returned by the all() method:

Range all = model.all();

Iterating over this range will produce statements in GSPO or SPO order, which is the natural order for writing nicely abbreviated documents.

In some more advanced cases, it is useful to iterate over a model in a specific order, for example to optimise an algorithm that performs several iterations at once. A range of all statements with a specific ordering can be had via the ordered() method:

Range ordered = model.ordered(StatementOrder::OPS);

Ranges work like immutable collections, and can be iterated over in the typical way:

for (const StatementView& statement : all) {
  std::cout << "Range statement subject: " << statement.subject()
            << std::endl;
}

Pattern Matching

There are several model methods that can be used to quickly find statements in the model that match a pattern. The simplest is ask() which checks if there is any matching statement:

Node rdf_type = make_uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");

if (model.ask({}, rdf_type, {}, {})) {
  std::cout << "Model contains a type statement" << std::endl;
}

To access the unknown fields, an iterator to the matching statement can be found with find() instead:

Iter it = model.find({}, rdf_type, {});

NodeView instance = it->subject();

Similar to ask(), count() can be used to count the number of matching statements:

size_t n = model.count(instance, rdf_type, {});
std::cout << "Instance has " << n << " types" << std::endl;

To iterate over matching statements, range() can be used, which returns a range that includes only statements that match the pattern:

for (const StatementView& statement : model.range(instance, rdf_type, {})) {
  std::cout << "Instance has type " << statement.object() << std::endl;
}

Indexing

A model can contain several indices that use different orderings to support different kinds of queries. For good performance, there should be an index where the least significant fields in the ordering correspond to wildcards in the pattern (or, in other words, one where the most significant fields in the ordering correspond to nodes given in the pattern). The table below lists the indices that best support a kind of pattern, where a “?” represents a wildcard.

Pattern

Good Indices

s p o

Any

s p ?

SPO, PSO

s ? o

SOP, OSP

s ? ?

SPO, SOP

? p o

POS, OPS

? p ?

POS, PSO

? ? o

OSP, OPS

? ? ?

Any

If graphs are enabled, then statements are indexed both with and without the graph fields, so queries with and without a graph wildcard will have similar performance.

Since indices take up space and slow down insertion, it is best to enable the fewest indices possible that cover the queries that will be performed. For example, an applications might enable just SPO and OPS order, because they always search for specific subjects or objects, but never for just a predicate without specifying any other field.

Getting Values

Sometimes you are only interested in a single node, and it is cumbersome to first search for a statement and then get the node from it. A more convenient way is to use the get() method. To get a value, specify a pattern where exactly one of the subject, predicate, and object is a wildcard. If a statement matches, then the node that “fills” the wildcard will be returned:

Optional<NodeView> t = model.get(instance, rdf_type, {});
if (t) {
  std::cout << "Instance has type " << *t << std::endl;
}

If multiple statements match the pattern, then the matching node from an arbitrary statement is returned. It is an error to specify more than one wildcard, excluding the graph.

The similar get_statement() instead returns the matching statement:

Optional<StatementView> ts = model.get_statement(instance, rdf_type, {});
if (ts) {
  std::cout << "Instance " << ts->subject() << " has type " << ts->object()
            << std::endl;
}

Erasing Statements

Individual statements can be erased with erase(), which takes an iterator:

Iter itype = model.find({}, rdf_type, {});
model.erase(itype);

There is also an overload that takes a range and erases all statements in that range:

Range all_types = model.range({}, rdf_type, {});
model.erase(all_types);

Erasing statements from a model invalidates all iterators to that model.

Reading and Writing

Reading and writing documents in a textual syntax is handled by the Reader and Writer, respectively. Serd is designed around a concept of event streams, so the reader or writer can be at the beginning or end of a “pipeline” of stream processors. This allows large documents to be processed quickly in an “online” fashion, while requiring only a small constant amount of memory. If you are familiar with XML, this is roughly analogous to SAX.

A common setup is to simply connect a reader directly to a writer. This can be used for things like pretty-printing, or converting a document from one syntax to another. This can be done by passing the sink returned by the writer’s sink() method to the reader constructor.

First though, an environment needs to be set up in order to write a document. This defines the base URI and any namespace prefixes, which are used to resolve any relative URIs or prefixed names by the reader, and to abbreviate the output by the writer. In most cases, the base URI should simply be the URI of the file being written. For example:

Node base = make_file_uri("/some/file.ttl");

Env env{base};

Namespace prefixes can also be defined for any vocabularies used:

env.set_prefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");

The reader will set any additional prefixes from the document as they are encountered.

We now have an environment set up for the contents of our document, but still need to specify where to write it. This is done by creating a ByteSink, which is a generic interface that can be set up to write to a file, a buffer in memory, or a custom function that can be used to write output anywhere. In this case, we will write to the file we set up as the base URI:

ByteSink out{"/tmp/eg.ttl", 4096};

The second argument is the page size in bytes, so I/O will be performed in chunks for better performance. The value used here, 4096, is a typical filesystem block size that should perform well on most machines.

With an environment and byte sink ready, the writer can now be created:

Writer writer{world, serd::Syntax::Turtle, {}, env, std::move(out)}; // FIXME

Output is written by feeding statements and other events to the sink returned by the writer’s sink() method. Sink is the generic interface for anything that can consume data streams. Many objects provide the same interface to do various things with the data, but in this case we will send data directly to the writer:

Reader reader{world, Syntax::Turtle, {}, env, writer.sink(), 4096};

The third argument of the reader constructor takes a bitwise OR of ReaderFlag flags that can be used to configure the reader. In this case no flags are given, but for example, passing ReaderFlag::lax | ReaderFlag::relative would enable lax mode and preserve relative URIs in the input.

Now that we have a reader that is set up to directly push its output to a writer, we can finally process the document:

Status st = reader.read_document();
if (st != Status::success) {
  std::cout << "Error reading document: " << strerror(st) << std::endl;
}

Alternatively, one “chunk” of input can be read at a time with read_chunk(). A “chunk” is generally one top-level description of a resource, including any anonymous blank nodes in its description, but this depends on the syntax and the structure of the document being read.

The reader pushes events to its sink as input is read, so in this scenario the data should now have been re-written by the writer (assuming no error occurred). To finish and ensure that a complete document has been read and written, Reader::finish() can be called followed by Writer::finish(). However these will be automatically called on destruction if necessary, so if the reader and writer are no longer required they can simply be destroyed.

Finally, closing the byte sink will flush and close the output file, so it is ready to be read again later. Similar to the reader and writer, this can be done explicitly by calling its close() method, or implicitly by destroying the byte sink if it is no longer needed:

out.close();

Reading into a Model

A document can be loaded into a model by setting up a reader that pushes data to a model inserter rather than a writer:

Model    model{world, ModelFlag::index_SPO};
Inserter inserter{model};

The process of reading the document is the same as above, only the sink is different:

Reader model_reader{world, Syntax::Turtle, {}, env, inserter, 4096};

st = model_reader.read_document();
if (st != Status::success) {
  std::cout << "Error loading model: " << strerror(st) << std::endl;
}

Writing a Model

A model, or parts of a model, can be written by writing the desired range using its Range::write() method:

model.all().write(writer.sink(), {});

By default, this writes the range in chunks suited to pretty-printing with anonymous blank nodes (like “[ … ]” in Turtle or TriG). The flag SerialisationFlag::no_inline_objects can be given to instead write the range in a simple SPO order, which can be useful in other situations because it is faster and emits statements in strictly increasing order.

Stream Processing

The above examples show how a document can be either written to a file or loaded into a model, simply by changing the sink that the data is written to. There are also sinks that filter or transform the data before passing it on to another sink, which can be used to build more advanced pipelines with several processing stages.

Canonical Literals

The “canon” is a stream processor that converts literals with supported XSD datatypes into canonical form. For example, this will rewrite an xsd:decimal literal like “.10” as “0.1”. A canon can be constructed by passing the “target” sink that the transformed statements should be written to, for example:

serd::Canon canon{world, inserter, {}};

The last argument is a bitwise OR of CanonFlag flags. For example, CanonFlag::lax will tolerate and pass through invalid literals, which can be useful for cleaning up questionabe data as much as possible without losing any information.

Filtering Statements

The “filter” is a stream processor that filters statements based on a pattern. It can be configured in either inclusive or exclusive mode, which passes through only statements that match or don’t match the pattern, respectively. A filter can be constructed by passing the target sink, the statement pattern as individual nodes, and an inclusive flag. For example, all statements with predicate rdf:type could be filtered out when loading a model:

serd::Filter filter{inserter, // Target
                    {},       // Subject
                    rdf_type, // Predicate
                    {},       // Object
                    {},       // Graph
                    true};    // Inclusive

If false is passed for the last parameter instead, then the filter operates in exclusive mode and will instead insert only statements with predicate rdf:type.

Serd C API

String View

struct SerdStringView

An immutable slice of a string.

This type is used for many string parameters, to allow referring to slices of strings in-place and to avoid redundant string measurement.

const char *buf

Start of string.

size_t len

Length of string in bytes.

SERD_EMPTY_STRING()

Return a view of an empty string.

SERD_STRING(str)

Return a view of an entire string by measuring it.

This makes a view of the given string by measuring it with strlen.

Parameters
  • str – Non-null pointer to the start of a null-terminated C string.

SERD_OPTIONAL_STRING(str)

Return a view of an entire string by measuring it, or the empty string.

This is the same as SERD_STRING(), but tolerates null, in which case an empty string view is returned.

Parameters
  • str – Pointer to the start of a null-terminated C string, or null.

SERD_SUBSTRING(str, len)

Return a view of a substring, or a premeasured string.

This makes either a view of a slice of a string (which may not be null terminated), or a view of a string that has already been measured. This is faster than SERD_STRING() for dynamic strings since it does not call strlen, so should be used when the length of the string is already known.

Parameters
  • str – Pointer to the start of the substring.

  • len – Length of the substring in bytes, not including the trailing null terminator if present.

Status Codes

enum SerdStatus

Return status code.

enumerator SERD_SUCCESS

No error.

enumerator SERD_FAILURE

Non-fatal failure.

enumerator SERD_ERR_UNKNOWN

Unknown error.

enumerator SERD_ERR_BAD_SYNTAX

Invalid syntax.

enumerator SERD_ERR_BAD_ARG

Invalid argument.

enumerator SERD_ERR_BAD_ITER

Use of invalidated iterator.

enumerator SERD_ERR_NOT_FOUND

Not found.

enumerator SERD_ERR_ID_CLASH

Encountered clashing blank node IDs.

enumerator SERD_ERR_BAD_CURIE

Invalid CURIE (e.g. prefix does not exist)

enumerator SERD_ERR_INTERNAL

Unexpected internal error (should not happen)

enumerator SERD_ERR_OVERFLOW

Stack overflow.

enumerator SERD_ERR_NO_DATA

Unexpected end of input.

enumerator SERD_ERR_BAD_TEXT

Invalid text encoding.

enumerator SERD_ERR_BAD_WRITE

Error writing to file/stream.

enumerator SERD_ERR_BAD_CALL

Invalid call.

enumerator SERD_ERR_BAD_URI

Invalid or unresolved URI.

enumerator SERD_ERR_INVALID

Invalid data.

const char *serd_strerror(SerdStatus status)

Return a string describing a status code.

String Utilities

void *serd_base64_decode(const char *str, size_t len, size_t *size)

Decode a base64 string.

This function can be used to decode a node created with serd_new_base64().

Parameters
  • str – Base64 string to decode.

  • len – The length of str.

  • size – Set to the size of the returned blob in bytes.

Returns

A newly allocated blob which must be freed with serd_free().

char *serd_canonical_path(const char *path)

Return path as a canonicalized absolute path.

This expands all symbolic links, relative references, and removes extra directory separators. Null is returned on error, including if the path does not exist.

Returns

A new string that must be freed with serd_free(), or null.

I/O Function Types

typedef size_t (*SerdReadFunc)(void *buf, size_t size, size_t nmemb, void *stream)

Source function for raw string input.

Identical semantics to fread, but may set errno for more informative error reporting than supported by SerdStreamErrorFunc.

Parameters
  • buf – Output buffer.

  • size – Size of a single element of data in bytes (always 1).

  • nmemb – Number of elements to read.

  • stream – Stream to read from (FILE* for fread).

Returns

Number of elements (bytes) read, which is short on error.

typedef size_t (*SerdWriteFunc)(const void *buf, size_t size, size_t nmemb, void *stream)

Sink function for raw string output.

Identical semantics to fwrite, but may set errno for more informative error reporting than supported by SerdStreamErrorFunc.

Parameters
  • buf – Input buffer.

  • size – Size of a single element of data in bytes (always 1).

  • nmemb – Number of elements to read.

  • stream – Stream to write to (FILE* for fread).

Returns

Number of elements (bytes) written, which is short on error.

typedef int (*SerdStreamErrorFunc)(void *stream)

Function to detect I/O stream errors.

Identical semantics to ferror.

Returns

Non-zero if stream has encountered an error.

typedef int (*SerdStreamCloseFunc)(void *stream)

Function to close an I/O stream.

Identical semantics to fclose.

Returns

Non-zero if stream has encountered an error.

Syntax Utilities

enum SerdSyntax

Syntax supported by serd.

enumerator SERD_SYNTAX_EMPTY

Empty syntax (suppress input or output)

enumerator SERD_TURTLE

Terse triples http://www.w3.org/TR/turtle.

enumerator SERD_NTRIPLES

Flat triples http://www.w3.org/TR/n-triples/.

enumerator SERD_NQUADS

Flat quads http://www.w3.org/TR/n-quads/.

enumerator SERD_TRIG

Terse quads http://www.w3.org/TR/trig/.

SerdSyntax serd_syntax_by_name(const char *name)

Get a syntax by name.

Case-insensitive, supports “Turtle”, “NTriples”, “NQuads”, and “TriG”. SERD_SYNTAX_EMPTY is returned if the name is not recognized.

SerdSyntax serd_guess_syntax(const char *filename)

Guess a syntax from a filename.

This uses the file extension to guess the syntax of a file. SERD_SYNTAX_EMPTY is returned if the extension is not recognized.

bool serd_syntax_has_graphs(SerdSyntax syntax)

Return whether a syntax can represent multiple graphs.

Returns

True for SERD_NQUADS and SERD_TRIG, false otherwise.

Data

URI

struct SerdURIView

A parsed URI.

This URI representation is designed for fast streaming, it allows creating relative URI references or resolving them into absolute URIs in-place without any string allocation.

Each component refers to slices in other strings, so a URI view must outlive any strings it was parsed from. The components are not necessarily null-terminated.

The scheme, authority, path, query, and fragment simply point to the string value of those components, not including any delimiters. The path_prefix is a special component for storing relative or resolved paths. If it points to a string (usually a base URI the URI was resolved against), then this string is prepended to the path. Otherwise, the length is interpret as the number of up-references (“../”) that must be prepended to the path.

SerdStringView scheme

Scheme.

SerdStringView authority

Authority.

SerdStringView path_prefix

Path prefix for relative/resolved paths.

SerdStringView path

Path suffix.

SerdStringView query

Query.

SerdStringView fragment

Fragment.

bool serd_uri_string_has_scheme(const char *string)

Return true iff string starts with a valid URI scheme.

SerdURIView serd_parse_uri(const char *string)

Parse string and return a URI view that points into it.

char *serd_parse_file_uri(const char *uri, char **hostname)

Get the unescaped path and hostname from a file URI.

The returned path and *hostname must be freed with serd_free().

Parameters
  • uri – A file URI.

  • hostname – If non-NULL, set to the hostname, if present.

Returns

A filesystem path.

SerdURIView serd_resolve_uri(SerdURIView r, SerdURIView base)

Return reference r resolved against base.

This will make r an absolute URI if possible.

RFC3986 5.2.2

Parameters
  • r – URI reference to make absolute, for example “child/path”.

  • base – Base URI, for example “http://example.org/base/”.

Returns

An absolute URI, for example “http://example.org/base/child/path”, or r if it is not a URI reference that can be resolved against base.

SerdURIView serd_relative_uri(SerdURIView r, SerdURIView base)

Return r as a reference relative to base if possible.

RFC3986 5.2.2

Parameters
Returns

A relative URI reference, for example “child/path”, r if it can not be made relative to base, or a null URI if r could be made relative to base, but the path prefix is already being used (most likely because r was previously a relative URI reference that was resolved against some base).

bool serd_uri_is_within(SerdURIView r, SerdURIView base)

Return whether r can be written as a reference relative to base.

For example, with basehttp://example.org/base/”, this returns true if r is also “http://example.org/base/”, or something like “http://example.org/base/child” (“child”) “http://example.org/base/child/grandchild#fragment” (“child/grandchild#fragment”), “http://example.org/base/child/grandchild?query” (“child/grandchild?query”), and so on.

Returns

True if r and base are equal or if r is a child of base.

size_t serd_uri_string_length(SerdURIView uri)

Return the length of uri as a string.

This can be used to get the expected number of bytes that will be written by serd_write_uri().

Returns

A string length in bytes, not including the null terminator.

size_t serd_write_uri(SerdURIView uri, SerdWriteFunc sink, void *stream)

Write uri as a string to sink.

This will call sink several times to emit the URI.

Parameters
  • uri – URI to write as a string.

  • sink – Sink to write string output to.

  • stream – Opaque user argument to pass to sink.

Returns

The number of bytes written, which is less than serd_uri_string_length(uri) on error.

Node

enum SerdNodeType

Type of a node.

An RDF node, in the abstract sense, can be either a resource, literal, or a blank. This type is more precise, because syntactically there are two ways to refer to a resource (by URI or CURIE). Serd also has support for variable nodes to support some features, which are not RDF nodes.

There are also two ways to refer to a blank node in syntax (by ID or anonymously), but this is handled by statement flags rather than distinct node types.

enumerator SERD_LITERAL

Literal value.

A literal optionally has either a language, or a datatype (not both).

enumerator SERD_LONG_LITERAL

Long literal value.

A long literal is the same data as a literal, but is written with long string syntax (triple quotes) to allow unescaped newlines.

enumerator SERD_URI

URI (absolute or relative).

Value is an unquoted URI string, which is either a relative reference with respect to the current base URI (e.g. “foo/bar”), or an absolute URI (e.g. “http://example.org/foo”). RFC3986

enumerator SERD_CURIE

CURIE, a shortened URI.

Value is an unquoted CURIE string relative to the current environment, e.g. “rdf:type”. CURIE Syntax 1.0

enumerator SERD_BLANK

A blank node.

Value is a blank node ID without any syntactic prefix, like “id3”, which is meaningful only within this serialisation. RDF 1.1 Turtle

enumerator SERD_VARIABLE

A variable node.

Value is a variable name without any syntactic prefix, like “name”, which is meaningful only within this serialisation. SPARQL 1.1 Query Language

typedef struct SerdNodeImpl SerdNode

An RDF node.

SerdNode *serd_node_from_syntax(const char *str, SerdSyntax syntax)

Create a node from a string representation in syntax.

The string should be a node as if written as an object in the given syntax, without any extra quoting or punctuation, which is the format returned by serd_node_to_syntax(). These two functions, when used with SERD_TURTLE, can be used to round-trip any node to a string and back.

Parameters
  • str – String representation of a node.

  • syntax – Syntax to use. Should be either SERD_TURTLE or SERD_NTRIPLES (the others are redundant). Note that namespaced (CURIE) nodes and relative URIs can not be expressed in NTriples.

Returns

A newly allocated node that must be freed with serd_node_free().

char *serd_node_to_syntax(const SerdNode *node, SerdSyntax syntax)

Return a string representation of node in syntax.

The returned string represents that node as if written as an object in the given syntax, without any extra quoting or punctuation.

Parameters
  • node – Node to write as a string.

  • syntax – Syntax to use. Should be either SERD_TURTLE or SERD_NTRIPLES (the others are redundant). Note that namespaced (CURIE) nodes and relative URIs can not be expressed in NTriples.

Returns

A newly allocated string that must be freed with serd_free().

SerdNode *serd_new_simple_node(SerdNodeType type, SerdStringView string)

Create a new “simple” node that is just a string.

This can be used to create nodes from an already measured string or slice of a buffer, which avoids measuring the string compared to the friendlier constructors. If type is SERD_LITERAL or SERD_LONG_LITERAL, then this creates a plain literal with no language tag.

Parameters
  • type – The type of node to create.

  • string – The string contents of the node.

SerdNode *serd_new_string(SerdStringView string)

Create a new plain literal string node from str

SerdNode *serd_new_plain_literal(SerdStringView str, SerdStringView lang)

Create a new plain literal node from str with lang.

A plain literal has no datatype, but may have a language tag. The lang may be empty, in which case this is equivalent to serd_new_string().

SerdNode *serd_new_typed_literal(SerdStringView str, SerdStringView datatype_uri)

Create a new typed literal node from str.

A typed literal has no language tag, but may have a datatype. The datatype may be NULL, in which case this is equivalent to serd_new_string().

SerdNode *serd_new_blank(SerdStringView string)

Create a new blank node.

SerdNode *serd_new_curie(SerdStringView string)

Create a new CURIE node.

SerdNode *serd_new_uri(SerdStringView string)

Create a new URI from a string.

SerdNode *serd_new_parsed_uri(SerdURIView uri)

Create a new URI from a URI view.

SerdNode *serd_new_file_uri(SerdStringView path, SerdStringView hostname)

Create a new file URI node from a file system path and optional hostname.

Backslashes in Windows paths will be converted, and other characters will be percent encoded as necessary.

If path is relative, hostname is ignored.

SerdNode *serd_new_boolean(bool b)

Create a new node by serialising b into an xsd:boolean string.

SerdNode *serd_new_decimal(double d, const SerdNode *datatype)

Create a new canonical xsd:decimal literal.

The resulting node will always contain a ‘.’, start with a digit, and end with a digit (a leading and/or trailing ‘0’ will be added if necessary), for example, “1.0”. It will never be in scientific notation.

Parameters
  • d – The value for the new node.

  • datatype – Datatype of node, or NULL for xsd:decimal.

SerdNode *serd_new_double(double d)

Create a new canonical xsd:double literal.

The returned node will always be in scientific notation, like “1.23E4”, except for NaN and negative/positive infinity, which are “NaN”, “-INF”, and “INF”, respectively.

Uses the shortest possible representation that precisely describes d, which has at most 17 significant digits (under 24 characters total).

Parameters

d – Double value to write.

Returns

A literal node with datatype xsd:double.

SerdNode *serd_new_float(float f)

Create a new canonical xsd:float literal.

Uses identical formatting to serd_new_double(), except with at most 9 significant digits (under 14 characters total).

Parameters

f – Float value of literal.

Returns

A literal node with datatype xsd:float.

SerdNode *serd_new_integer(int64_t i, const SerdNode *datatype)

Create a new canonical xsd:integer literal.

Parameters
  • i – Integer value of literal.

  • datatype – Datatype of node, or NULL for xsd:integer.

SerdNode *serd_new_base64(const void *buf, size_t size, const SerdNode *datatype)

Create a new canonical xsd:base64Binary literal.

This function can be used to make a node out of arbitrary binary data, which can be decoded using serd_base64_decode().

Parameters
  • buf – Raw binary data to encode in node.

  • size – Size of buf in bytes.

  • datatype – Datatype of node, or null for xsd:base64Binary.

bool serd_get_boolean(const SerdNode *node)

Return the value of node as a boolean.

This will work for booleans, and numbers of any datatype if they are 0 or 1.

Returns

The value of node as a bool, or false on error.

double serd_get_double(const SerdNode *node)

Return the value of node as a double.

This will coerce numbers of any datatype to double, if the value fits.

Returns

The value of node as a double, or NaN on error.

float serd_get_float(const SerdNode *node)

Return the value of node as a float.

This will coerce numbers of any datatype to float, if the value fits.

Returns

The value of node as a float, or NaN on error.

int64_t serd_get_integer(const SerdNode *node)

Return the value of node as a long (signed 64-bit integer).

This will coerce numbers of any datatype to long, if the value fits.

Returns

The value of node as a int64_t, or 0 on error.

SerdNode *serd_node_copy(const SerdNode *node)

Return a deep copy of node

void serd_node_free(SerdNode *node)

Free any data owned by node

SerdNodeType serd_node_type(const SerdNode *node)

Return the type of a node.

const char *serd_node_string(const SerdNode *node)

Return the string value of a node.

size_t serd_node_length(const SerdNode *node)

Return the length of the string value of a node in bytes.

SerdStringView serd_node_string_view(const SerdNode *node)

Return a view of the string in a node.

This is a convenience wrapper for serd_node_string() and serd_node_length() that can be used to get both in a single call.

SerdURIView serd_node_uri_view(const SerdNode *node)

Return a parsed view of the URI in a node.

It is best to check the node type before calling this function, though it is safe to call on non-URI nodes. In that case, it will return a null view with all fields zero.

Note that this parses the URI string contained in the node, so it is a good idea to keep the value if you will be using it several times in the same scope.

const SerdNode *serd_node_datatype(const SerdNode *node)

Return the datatype of a literal node, or NULL.

const SerdNode *serd_node_language(const SerdNode *node)

Return the language tag of a literal node, or NULL.

bool serd_node_equals(const SerdNode *a, const SerdNode *b)

Return true iff a is equal to b

int serd_node_compare(const SerdNode *a, const SerdNode *b)

Compare two nodes.

Returns less than, equal to, or greater than zero if a is less than, equal to, or greater than b, respectively. NULL is treated as less than any other node.

Nodes

typedef struct SerdNodesImpl SerdNodes

Hashing node container for interning and simplified memory management.

SerdNodes *serd_nodes_new(void)

Create a new node set.

void serd_nodes_free(SerdNodes *nodes)

Free nodes and all nodes that are stored in it.

Note that this invalidates any pointers previously returned from serd_nodes_intern() or serd_nodes_manage() calls on nodes.

size_t serd_nodes_size(const SerdNodes *nodes)

Return the number of nodes in nodes

const SerdNode *serd_nodes_intern(SerdNodes *nodes, const SerdNode *node)

Intern node.

Multiple calls with equivalent nodes will return the same pointer.

Returns

A node that is different than, but equivalent to, node.

const SerdNode *serd_nodes_manage(SerdNodes *nodes, SerdNode *node)

Manage node.

Like serd_nodes_intern, but takes ownership of node, freeing it and returning a previously interned/managed equivalent node if necessary.

Returns

A node that is equivalent to node.

void serd_nodes_deref(SerdNodes *nodes, const SerdNode *node)

Dereference node.

Decrements the reference count of node, and frees the internally stored equivalent node if this was the last reference. Does nothing if no node equivalent to node is stored in nodes.

Cursor

typedef struct SerdCursorImpl SerdCursor

The origin of a statement in a document.

SerdCursor *serd_cursor_new(const SerdNode *name, unsigned line, unsigned col)

Create a new cursor.

Note that, to minimise model overhead, the cursor does not own the name node, so name must have a longer lifetime than the cursor for it to be valid. That is, serd_cursor_name() will return exactly the pointer name, not a copy. For cursors from models, this is the lifetime of the model. For user-created cursors, the simplest way to handle this is to use SerdNodes.

Parameters
  • name – The name of the document or stream (usually a file URI)

  • line – The line number in the document (1-based)

  • col – The column number in the document (1-based)

Returns

A new cursor that must be freed with serd_cursor_free()

SerdCursor *serd_cursor_copy(const SerdCursor *cursor)

Return a copy of cursor

void serd_cursor_free(SerdCursor *cursor)

Free cursor

bool serd_cursor_equals(const SerdCursor *lhs, const SerdCursor *rhs)

Return true iff lhs is equal to rhs

const SerdNode *serd_cursor_name(const SerdCursor *cursor)

Return the document name.

This is typically a file URI, but may be a descriptive string node for statements that originate from streams.

unsigned serd_cursor_line(const SerdCursor *cursor)

Return the one-relative line number in the document.

unsigned serd_cursor_column(const SerdCursor *cursor)

Return the zero-relative column number in the line.

Statement

enum SerdField

Index of a node in a statement.

enumerator SERD_SUBJECT

Subject.

enumerator SERD_PREDICATE

Predicate (“key”)

enumerator SERD_OBJECT

Object (“value”)

enumerator SERD_GRAPH

Graph (“context”)

typedef struct SerdStatementImpl SerdStatement

A subject, predicate, and object, with optional graph context.

SerdStatement *serd_statement_new(const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g, const SerdCursor *cursor)

Create a new statement.

Note that, to minimise model overhead, statements do not own their nodes, so they must have a longer lifetime than the statement for it to be valid. For statements in models, this is the lifetime of the model. For user-created statements, the simplest way to handle this is to use SerdNodes.

Parameters
  • s – The subject

  • p – The predicate (“key”)

  • o – The object (“value”)

  • g – The graph (“context”)

  • cursor – Optional cursor at the origin of this statement

Returns

A new statement that must be freed with serd_statement_free()

SerdStatement *serd_statement_copy(const SerdStatement *statement)

Return a copy of statement

void serd_statement_free(SerdStatement *statement)

Free statement

const SerdNode *serd_statement_node(const SerdStatement *statement, SerdField field)

Return the given node of the statement.

const SerdNode *serd_statement_subject(const SerdStatement *statement)

Return the subject of the statement.

const SerdNode *serd_statement_predicate(const SerdStatement *statement)

Return the predicate of the statement.

const SerdNode *serd_statement_object(const SerdStatement *statement)

Return the object of the statement.

const SerdNode *serd_statement_graph(const SerdStatement *statement)

Return the graph of the statement.

const SerdCursor *serd_statement_cursor(const SerdStatement *statement)

Return the source location where the statement originated, or NULL.

bool serd_statement_equals(const SerdStatement *a, const SerdStatement *b)

Return true iff a is equal to b, ignoring statement cursor metadata.

Only returns true if nodes are equivalent, does not perform wildcard matching.

bool serd_statement_matches(const SerdStatement *statement, const SerdNode *subject, const SerdNode *predicate, const SerdNode *object, const SerdNode *graph)

Return true iff the statement matches the given pattern.

Nodes match if they are equivalent, or if one of them is NULL. The statement matches if every node matches.

World

Logging

struct SerdLogField

A structured log field.

This can be used to pass additional information along with log messages. Syslog-compatible keys should be used where possible, otherwise, keys should be namespaced to prevent clashes.

Serd itself uses the following keys: - ERRNO

  • SERD_COL

  • SERD_FILE

  • SERD_LINE

  • SERD_STATUS

const char *key

Field name.

const char *value

Field value.

struct SerdLogEntry

A log entry (message).

This is the description of a log entry which is passed to log functions. It is only valid in the stack frame it appears in, and may not be copied.

An entry is a single self-contained message, so the string should not include a trailing newline.

const SerdLogField *fields

Extra log fields.

const char *fmt

Printf-style format string.

va_list *args

Arguments for fmt

SerdLogLevel level

Log level.

size_t n_fields

Number of fields

enum SerdLogLevel

Log message level, compatible with syslog.

enumerator SERD_LOG_LEVEL_EMERGENCY

Emergency, system is unusable.

enumerator SERD_LOG_LEVEL_ALERT

Action must be taken immediately.

enumerator SERD_LOG_LEVEL_CRITICAL

Critical condition.

enumerator SERD_LOG_LEVEL_ERROR

Error.

enumerator SERD_LOG_LEVEL_WARNING

Warning.

enumerator SERD_LOG_LEVEL_NOTICE

Normal but significant condition.

enumerator SERD_LOG_LEVEL_INFO

Informational message.

enumerator SERD_LOG_LEVEL_DEBUG

Debug message.

typedef SerdStatus (*SerdLogFunc)(void *handle, const SerdLogEntry *entry)

Sink function for log messages.

Parameters
  • handle – Handle for user data.

  • entry – Pointer to log entry description.

SerdStatus serd_quiet_error_func(void *handle, const SerdLogEntry *entry)

A SerdLogFunc that does nothing, for suppressing log output.

const char *serd_log_entry_get_field(const SerdLogEntry *entry, const char *key)

Return the value of the log field named key, or NULL if none exists.

void serd_world_set_log_func(SerdWorld *world, SerdLogFunc log_func, void *handle)

Set a function to be called with log messages (typically errors).

If no custom logging function is set, then messages are printed to stderr.

Parameters
  • world – World that will send log entries to the given function.

  • log_func – Log function to call for every log message. Each call to this function represents a complete log message with an implicit trailing newline.

  • handle – Opaque handle that will be passed to every invocation of log_func.

SerdStatus serd_world_logf(const SerdWorld *world, SerdLogLevel level, size_t n_fields, const SerdLogField *fields, const char *fmt, ...)

Write a message to the log.

This writes a single complete entry to the log, and so may not be used to print parts of a line like a more general printf-like function. There should be no trailing newline in fmt. Arguments following fmt should correspond to conversion specifiers in the format string as in printf from the standard C library.

Parameters
  • world – World to log to.

  • level – Log level.

  • n_fields – Number of entries in fields.

  • fields – An array of n_fields extra log fields.

  • fmt – Format string.

SerdStatus serd_world_vlogf(const SerdWorld *world, SerdLogLevel level, size_t n_fields, const SerdLogField *fields, const char *fmt, va_list args)

Write a message to the log with a va_list.

This is the same as serd_world_logf() except it takes format arguments as a va_list for composability.

struct SerdError

An error description.

SerdStatus status

Error code.

const SerdCursor *cursor

Origin of error.

const char *fmt

Printf-style format string.

va_list *args

Arguments for fmt.

typedef struct SerdWorldImpl SerdWorld

Global library state.

SerdWorld *serd_world_new(void)

Create a new Serd World.

It is safe to use multiple worlds in one process, though no objects can be shared between worlds.

void serd_world_free(SerdWorld *world)

Free world

SerdNodes *serd_world_nodes(SerdWorld *world)

Return the nodes cache in world.

The returned cache is owned by the world and contains various nodes used frequently by the implementation. For convenience, it may be used to store additional nodes which will be freed when the world is freed.

const SerdNode *serd_world_get_blank(SerdWorld *world)

Return a unique blank node.

The returned node is valid only until the next time serd_world_get_blank() is called or the world is destroyed.

Data Streaming

Events

struct SerdBaseEvent

Event for base URI changes.

Emitted whenever the base URI changes.

SerdEventType type

SERD_BASE

const SerdNode *uri

Base URI.

struct SerdPrefixEvent

Event for namespace definitions.

Emitted whenever a prefix is defined.

SerdEventType type

SERD_PREFIX

const SerdNode *name

Prefix name.

const SerdNode *uri

Namespace URI.

struct SerdStatementEvent

Event for statements.

Emitted for every statement.

SerdEventType type

SERD_STATEMENT

SerdStatementFlags flags

Flags for pretty-printing.

const SerdStatement *statement

Statement.

struct SerdEndEvent

Event for the end of anonymous node descriptions.

This is emitted to indicate that the given anonymous node will no longer be described. This is used by the writer which may, for example, need to write a delimiter.

SerdEventType type

SERD_END

const SerdNode *node

Anonymous node that is finished.

union SerdEvent

An event in a data stream.

Streams of data are represented as a series of events. Events represent everything that can occur in an RDF document, and are used to plumb together different components. For example, when parsing a document, a reader emits a stream of events which can be sent to a writer to rewrite a document, or to an inserter to build a model in memory.

SerdEventType type

Event type (always set)

SerdBaseEvent base

Base URI changed.

SerdPrefixEvent prefix

New namespace prefix.

SerdStatementEvent statement

Statement.

SerdEndEvent end

End of anonymous node.

enum SerdEventType

Type of a SerdEvent.

enumerator SERD_BASE

Base URI changed.

enumerator SERD_PREFIX

New URI prefix.

enumerator SERD_STATEMENT

Statement.

enumerator SERD_END

End of anonymous node.

enum SerdStatementFlag

Flags indicating inline abbreviation information for a statement.

enumerator SERD_EMPTY_S

Empty blank node subject.

enumerator SERD_ANON_S

Start of anonymous subject.

enumerator SERD_ANON_O

Start of anonymous object.

enumerator SERD_LIST_S

Start of list subject.

enumerator SERD_LIST_O

Start of list object.

enumerator SERD_TERSE_S

Start of terse subject.

enumerator SERD_TERSE_O

Start of terse object.

typedef uint32_t SerdStatementFlags

Bitwise OR of SerdStatementFlag values.

typedef SerdStatus (*SerdEventFunc)(void *handle, const SerdEvent *event)

Function for handling events.

Sink

typedef struct SerdSinkImpl SerdSink

An interface that receives a stream of RDF data.

typedef void (*SerdFreeFunc)(void *ptr)

Function to free an opaque handle.

SerdSink *serd_sink_new(void *handle, SerdEventFunc event_func, SerdFreeFunc free_handle)

Create a new sink.

Initially, the sink has no set functions and will do nothing. Use the serd_sink_set_*_func functions to set handlers for various events.

Parameters
  • handle – Opaque handle that will be passed to sink functions.

  • event_func – Function that will be called for every event

  • free_handle – Free function to call on handle in serd_sink_free().

void serd_sink_free(SerdSink *sink)

Free sink

SerdStatus serd_sink_write_event(const SerdSink *sink, const SerdEvent *event)

Send an event to the sink.

SerdStatus serd_sink_write_base(const SerdSink *sink, const SerdNode *uri)

Set the base URI.

SerdStatus serd_sink_write_prefix(const SerdSink *sink, const SerdNode *name, const SerdNode *uri)

Set a namespace prefix.

SerdStatus serd_sink_write_statement(const SerdSink *sink, SerdStatementFlags flags, const SerdStatement *statement)

Write a statement.

SerdStatus serd_sink_write(const SerdSink *sink, SerdStatementFlags flags, const SerdNode *subject, const SerdNode *predicate, const SerdNode *object, const SerdNode *graph)

Write a statement from individual nodes.

SerdStatus serd_sink_write_end(const SerdSink *sink, const SerdNode *node)

Mark the end of an anonymous node.

Canon

enum SerdCanonFlag

Flags that control canonical node transformation.

enumerator SERD_CANON_LAX

Tolerate and pass through invalid input.

typedef uint32_t SerdCanonFlags

Bitwise OR of SerdCanonFlag values.

SerdSink *serd_canon_new(const SerdWorld *world, const SerdSink *target, SerdCanonFlags flags)

Return a sink that transforms literals to canonical form where possible.

The returned sink acts like target in all respects, except literal nodes in statements may be modified from the original.

Filter

SerdSink *serd_filter_new(const SerdSink *target, const SerdNode *subject, const SerdNode *predicate, const SerdNode *object, const SerdNode *graph, bool inclusive)

Return a sink that filters out statements that do not match a pattern.

The returned sink acts like target in all respects, except that some statements may be dropped. If inclusive is true, then only statements that match the pattern are passed through. Otherwise, only statements that do not match the pattern are passed through.

Environment

typedef struct SerdEnvImpl SerdEnv

Lexical environment for relative URIs or CURIEs (base URI and namespaces)

SerdEnv *serd_env_new(SerdStringView base_uri)

Create a new environment.

SerdEnv *serd_env_copy(const SerdEnv *env)

Copy an environment.

bool serd_env_equals(const SerdEnv *a, const SerdEnv *b)

Return true iff a is equal to b

void serd_env_free(SerdEnv *env)

Free env

const SerdNode *serd_env_base_uri(const SerdEnv *env)

Get the current base URI.

SerdStatus serd_env_set_base_uri(SerdEnv *env, SerdStringView uri)

Set the current base URI.

SerdStatus serd_env_set_prefix(SerdEnv *env, SerdStringView name, SerdStringView uri)

Set a namespace prefix.

A namespace prefix is used to expand CURIE nodes, for example, with the prefix “xsd” set to “http://www.w3.org/2001/XMLSchema#”, “xsd:decimal” will expand to “http://www.w3.org/2001/XMLSchema#decimal”.

SerdNode *serd_env_qualify(const SerdEnv *env, const SerdNode *uri)

Qualify uri into a CURIE if possible.

Returns null if uri can not be qualified (usually because no corresponding prefix is defined).

SerdNode *serd_env_expand(const SerdEnv *env, const SerdNode *node)

Expand node, transforming CURIEs and URI references into absolute URIs.

If node is a relative URI reference, it is expanded to a full URI if possible. If node is a literal, its datatype is expanded if necessary. If node is a CURIE, it is expanded to a full URI if possible.

Returns null if node can not be expanded.

void serd_env_write_prefixes(const SerdEnv *env, const SerdSink *sink)

Write all prefixes in env to sink

Reading and Writing

Byte Source

typedef struct SerdByteSourceImpl SerdByteSource

A source for bytes that provides text input.

SerdByteSource *serd_byte_source_new_string(const char *string, const SerdNode *name)

Create a new byte source that reads from a string.

Parameters
  • string – Null-terminated UTF-8 string to read from.

  • name – Optional name of stream for error messages (string or URI).

SerdByteSource *serd_byte_source_new_filename(const char *path, size_t page_size)

Create a new byte source that reads from a file.

An arbitrary FILE* can be used via serd_byte_source_new_function() as well, this is just a convenience function that opens the file properly, sets flags for optimized I/O if possible, and automatically sets the name of the source to the file path.

Parameters
  • path – Path of file to open and read from.

  • page_size – Number of bytes to read per call.

SerdByteSource *serd_byte_source_new_function(SerdReadFunc read_func, SerdStreamErrorFunc error_func, SerdStreamCloseFunc close_func, void *stream, const SerdNode *name, size_t page_size)

Create a new byte source that reads from a user-specified function.

The stream will be passed to the read_func, which is compatible with the standard C fread if stream is a FILE*. Note that the reader only ever reads individual bytes at a time, that is, the size parameter will always be 1 (but nmemb may be higher).

Parameters
  • read_func – Streadm read function, like fread.

  • error_func – Stream error function, like ferror.

  • close_func – Stream close function, like fclose.

  • stream – Context parameter passed to read_func and error_func.

  • name – Optional name of stream for error messages (string or URI).

  • page_size – Number of bytes to read per call.

void serd_byte_source_free(SerdByteSource *source)

Free source

Reader

enum SerdReaderFlag

Reader options.

enumerator SERD_READ_LAX

Tolerate invalid input where possible.

enumerator SERD_READ_VARIABLES

Support variable nodes.

enumerator SERD_READ_EXACT_BLANKS

Allow clashes with generated blanks.

enumerator SERD_READ_PREFIXED

Do not expand prefixed names.

enumerator SERD_READ_RELATIVE

Do not expand relative URI references.

typedef struct SerdReaderImpl SerdReader

Streaming parser that reads a text stream and writes to a statement sink.

typedef uint32_t SerdReaderFlags

Bitwise OR of SerdReaderFlag values.

SerdReader *serd_reader_new(SerdWorld *world, SerdSyntax syntax, SerdReaderFlags flags, SerdEnv *env, const SerdSink *sink, size_t stack_size)

Create a new RDF reader.

void serd_reader_add_blank_prefix(SerdReader *reader, const char *prefix)

Set a prefix to be added to all blank node identifiers.

This is useful when multiple files are to be parsed into the same output (a model or a file). Since Serd preserves blank node IDs, this could cause conflicts where two non-equivalent blank nodes are merged, resulting in corrupt data. By setting a unique blank node prefix for each parsed file, this can be avoided, while preserving blank node names.

SerdStatus serd_reader_start(SerdReader *reader, SerdByteSource *byte_source)

Prepare to read from a byte source.

SerdStatus serd_reader_read_chunk(SerdReader *reader)

Read a single “chunk” of data during an incremental read.

This function will read a single top level description, and return. This may be a directive, statement, or several statements; essentially it reads until a ‘.’ is encountered. This is particularly useful for reading directly from a pipe or socket.

SerdStatus serd_reader_read_document(SerdReader *reader)

Read a complete document from the source.

This function will continue pulling from the source until a complete document has been read. Note that this may block when used with streams, for incremental reading use serd_reader_read_chunk().

SerdStatus serd_reader_finish(SerdReader *reader)

Finish reading from the source.

This should be called before starting to read from another source.

void serd_reader_free(SerdReader *reader)

Free reader.

The reader will be finished via serd_reader_finish() if necessary.

Byte Sink

typedef struct SerdByteSinkImpl SerdByteSink

A sink for bytes that receives text output.

SerdByteSink *serd_byte_sink_new_buffer(SerdBuffer *buffer)

Create a new byte sink that writes to a buffer.

The buffer is owned by the caller, but will be expanded as necessary.

Parameters

buffer – Buffer to write output to.

SerdByteSink *serd_byte_sink_new_filename(const char *path, size_t block_size)

Create a new byte sink that writes to a file.

An arbitrary FILE* can be used via serd_byte_sink_new_function() as well, this is just a convenience function that opens the file properly and sets flags for optimized I/O if possible.

Parameters
  • path – Path of file to open and write to.

  • block_size – Number of bytes to write per call.

SerdByteSink *serd_byte_sink_new_function(SerdWriteFunc write_func, void *stream, size_t block_size)

Create a new byte sink that writes to a user-specified function.

The stream will be passed to the write_func, which is compatible with the standard C fwrite if stream is a FILE*.

Parameters
  • write_func – Function called with bytes to consume.

  • stream – Context parameter passed to sink.

  • block_size – Number of bytes to write per call.

void serd_byte_sink_flush(SerdByteSink *sink)

Flush any pending output in sink to the underlying write function.

SerdStatus serd_byte_sink_close(SerdByteSink *sink)

Close sink, including the underlying file if necessary.

If sink was created with serd_byte_sink_new_filename(), then the file is closed. If there was an error, then SERD_ERR_UNKNOWN is returned and errno is set.

void serd_byte_sink_free(SerdByteSink *sink)

Free sink, flushing and closing first if necessary.

Writer

enum SerdWriterFlag

Writer style options.

These flags allow more precise control of writer output style. Note that some options are only supported for some syntaxes, for example, NTriples does not support abbreviation and is always ASCII.

enumerator SERD_WRITE_ASCII

Escape all non-ASCII characters.

enumerator SERD_WRITE_UNQUALIFIED

Do not shorten URIs into CURIEs.

enumerator SERD_WRITE_UNRESOLVED

Do not make URIs relative.

enumerator SERD_WRITE_TERSE

Write terser output without newlines.

enumerator SERD_WRITE_LAX

Tolerate lossy output.

typedef struct SerdWriterImpl SerdWriter

Streaming writer that writes a text stream as it receives events.

typedef uint32_t SerdWriterFlags

Bitwise OR of SerdWriterFlag values.

SerdWriter *serd_writer_new(SerdWorld *world, SerdSyntax syntax, SerdWriterFlags flags, const SerdEnv *env, SerdByteSink *byte_sink)

Create a new RDF writer.

void serd_writer_free(SerdWriter *writer)

Free writer

const SerdSink *serd_writer_sink(SerdWriter *writer)

Return a sink interface that emits statements via writer

const SerdEnv *serd_writer_env(const SerdWriter *writer)

Return the env used by writer

size_t serd_buffer_sink(const void *buf, size_t size, size_t nmemb, void *stream)

A convenience sink function for writing to a string.

This function can be used as a SerdSink to write to a SerdBuffer which is resized as necessary with realloc(). The stream parameter must point to an initialized SerdBuffer. When the write is finished, the string should be retrieved with serd_buffer_sink_finish().

char *serd_buffer_sink_finish(SerdBuffer *stream)

Finish writing to a buffer with serd_buffer_sink().

The returned string is the result of the serialisation, which is null terminated (by this function) and owned by the caller.

void serd_writer_chop_blank_prefix(SerdWriter *writer, const char *prefix)

Set a prefix to be removed from matching blank node identifiers.

This is the counterpart to serd_reader_add_blank_prefix() which can be used to “undo” added prefixes.

SerdStatus serd_writer_set_base_uri(SerdWriter *writer, const SerdNode *uri)

Set the current output base URI, and emit a directive if applicable.

Note this function can be safely casted to SerdBaseSink.

SerdStatus serd_writer_set_root_uri(SerdWriter *writer, const SerdNode *uri)

Set the current root URI.

The root URI should be a prefix of the base URI. The path of the root URI is the highest path any relative up-reference can refer to. For example, with root file:///foo/root and base file:///foo/root/base, file:///foo/root will be written as <../>, but file:///foo will be written non-relatively as file:///foo. If the root is not explicitly set, it defaults to the base URI, so no up-references will be created at all.

SerdStatus serd_writer_finish(SerdWriter *writer)

Finish a write.

This flushes any pending output, for example terminating punctuation, so that the output is a complete document.

enum SerdValidatorCheck

Validator checks.

enumerator SERD_CHECK_ALL_VALUES_FROM
enumerator SERD_CHECK_ANY_URI
enumerator SERD_CHECK_CARDINALITY_EQUAL
enumerator SERD_CHECK_CARDINALITY_MAX
enumerator SERD_CHECK_CARDINALITY_MIN
enumerator SERD_CHECK_CLASS_CYCLE
enumerator SERD_CHECK_CLASS_LABEL
enumerator SERD_CHECK_DATATYPE_PROPERTY
enumerator SERD_CHECK_DATATYPE_TYPE
enumerator SERD_CHECK_DEPRECATED_CLASS
enumerator SERD_CHECK_DEPRECATED_PROPERTY
enumerator SERD_CHECK_FUNCTIONAL_PROPERTY
enumerator SERD_CHECK_INSTANCE_LITERAL
enumerator SERD_CHECK_INSTANCE_TYPE
enumerator SERD_CHECK_INVERSE_FUNCTIONAL_PROPERTY
enumerator SERD_CHECK_LITERAL_INSTANCE
enumerator SERD_CHECK_LITERAL_MAX_EXCLUSIVE
enumerator SERD_CHECK_LITERAL_MAX_INCLUSIVE
enumerator SERD_CHECK_LITERAL_MIN_EXCLUSIVE
enumerator SERD_CHECK_LITERAL_MIN_INCLUSIVE
enumerator SERD_CHECK_LITERAL_PATTERN
enumerator SERD_CHECK_LITERAL_RESTRICTION
enumerator SERD_CHECK_LITERAL_VALUE
enumerator SERD_CHECK_OBJECT_PROPERTY
enumerator SERD_CHECK_PLAIN_LITERAL_DATATYPE
enumerator SERD_CHECK_PREDICATE_TYPE
enumerator SERD_CHECK_PROPERTY_CYCLE
enumerator SERD_CHECK_PROPERTY_DOMAIN
enumerator SERD_CHECK_PROPERTY_LABEL
enumerator SERD_CHECK_PROPERTY_RANGE
enumerator SERD_CHECK_SOME_VALUES_FROM
typedef struct SerdValidatorImpl SerdValidator

Validator

typedef uint64_t SerdValidatorChecks

Bitwise OR of SerdValidatorCheck values.

SerdValidator *serd_validator_new(SerdWorld *world)

Create a new validator.

void serd_validator_free(SerdValidator *validator)

Free validator

SerdStatus serd_validator_enable_checks(SerdValidator *validator, const char *pattern)

Enable validator checks that match a pattern.

SerdStatus serd_validator_disable_checks(SerdValidator *validator, const char *pattern)

Disable validator checks that match a pattern.

Storage

Iterator

typedef struct SerdIterImpl SerdIter

An iterator that points to a statement in a model.

SerdIter *serd_iter_copy(const SerdIter *iter)

Return a new copy of iter

const SerdStatement *serd_iter_get(const SerdIter *iter)

Return the statement pointed to by iter

bool serd_iter_next(SerdIter *iter)

Increment iter to point to the next statement.

Returns

True iff iter has reached the end.

bool serd_iter_equals(const SerdIter *lhs, const SerdIter *rhs)

Return true iff lhs is equal to rhs

void serd_iter_free(SerdIter *iter)

Free iter

Range

enum SerdSerialisationFlag

Flags that control the style of a model serialisation.

enumerator SERD_NO_INLINE_OBJECTS

Disable object inlining.

typedef struct SerdRangeImpl SerdRange

A range of statements in a model.

typedef uint32_t SerdSerialisationFlags

Bitwise OR of SerdStatementFlag values.

SerdRange *serd_range_copy(const SerdRange *range)

Return a new copy of range

void serd_range_free(SerdRange *range)

Free range

const SerdStatement *serd_range_front(const SerdRange *range)

Return the first statement in range, or NULL if range is empty.

bool serd_range_equals(const SerdRange *lhs, const SerdRange *rhs)

Return true iff lhs is equal to rhs

bool serd_range_next(SerdRange *range)

Increment the start of range to point to the next statement.

bool serd_range_empty(const SerdRange *range)

Return true iff there are no statements in range

const SerdIter *serd_range_cbegin(const SerdRange *range)

Return an iterator to the start of range

const SerdIter *serd_range_cend(const SerdRange *range)

Return an iterator to the end of range

SerdIter *serd_range_begin(SerdRange *range)

Return an iterator to the start of range

SerdIter *serd_range_end(SerdRange *range)

Return an iterator to the end of range

SerdStatus serd_write_range(const SerdRange *range, const SerdSink *sink, SerdSerialisationFlags flags)

Write range to sink.

The serialisation style can be controlled with flags. The default is to write statements in an order suited for pretty-printing with Turtle or TriG with as many objects written inline as possible. If SERD_NO_INLINE_OBJECTS is given, a simple sorted stream is written instead, which is significantly faster since no searching is required, but can result in ugly output for Turtle or Trig.

Model

enum SerdStatementOrder

Statement ordering.

Statements themselves always have the same fields in the same order (subject, predicate, object, graph), but a model can keep indices for different orderings to provide good performance for different kinds of queries.

enumerator SERD_ORDER_SPO

Subject, Predicate, Object.

enumerator SERD_ORDER_SOP

Subject, Object, Predicate.

enumerator SERD_ORDER_OPS

Object, Predicate, Subject.

enumerator SERD_ORDER_OSP

Object, Subject, Predicate.

enumerator SERD_ORDER_PSO

Predicate, Subject, Object.

enumerator SERD_ORDER_POS

Predicate, Object, Subject.

enumerator SERD_ORDER_GSPO

Graph, Subject, Predicate, Object.

enumerator SERD_ORDER_GSOP

Graph, Subject, Object, Predicate.

enumerator SERD_ORDER_GOPS

Graph, Object, Predicate, Subject.

enumerator SERD_ORDER_GOSP

Graph, Object, Subject, Predicate.

enumerator SERD_ORDER_GPSO

Graph, Predicate, Subject, Object.

enumerator SERD_ORDER_GPOS

Graph, Predicate, Object, Subject.

enum SerdModelFlag

Flags that control model storage and indexing.

enumerator SERD_INDEX_SPO

Subject, Predicate, Object.

enumerator SERD_INDEX_SOP

Subject, Object, Predicate.

enumerator SERD_INDEX_OPS

Object, Predicate, Subject.

enumerator SERD_INDEX_OSP

Object, Subject, Predicate.

enumerator SERD_INDEX_PSO

Predicate, Subject, Object.

enumerator SERD_INDEX_POS

Predicate, Object, Subject.

enumerator SERD_INDEX_GRAPHS

Support multiple graphs in model.

enumerator SERD_STORE_CURSORS

Store original cursor of statements.

typedef struct SerdModelImpl SerdModel

An indexed set of statements.

typedef uint32_t SerdModelFlags

Bitwise OR of SerdModelFlag values.

SerdModel *serd_model_new(SerdWorld *world, SerdModelFlags flags)

Create a new model.

Parameters
  • world – The world in which to make this model.

  • flags – Model options, including enabled indices, for example SERD_SPO | SERD_OPS. Be sure to enable an index where the most significant node(s) are not variables in your queries. For example, to make (? P O) queries, enable either SERD_OPS or SERD_POS.

SerdModel *serd_model_copy(const SerdModel *model)

Return a deep copy of model

bool serd_model_equals(const SerdModel *a, const SerdModel *b)

Return true iff a is equal to b, ignoring statement cursor metadata.

void serd_model_free(SerdModel *model)

Close and free model

SerdWorld *serd_model_world(SerdModel *model)

Get the world associated with model

SerdNodes *serd_model_nodes(SerdModel *model)

Get all nodes interned in model

SerdModelFlags serd_model_flags(const SerdModel *model)

Get the flags enabled on model

size_t serd_model_size(const SerdModel *model)

Return the number of statements stored in model

bool serd_model_empty(const SerdModel *model)

Return true iff there are no statements stored in model

SerdIter *serd_model_begin(const SerdModel *model)

Return an iterator to the start of model

const SerdIter *serd_model_end(const SerdModel *model)

Return an iterator to the end of model

SerdRange *serd_model_all(const SerdModel *model)

Return a range of all statements in model in SPO order.

SerdRange *serd_model_ordered(const SerdModel *model, SerdStatementOrder order)

Return a range of all statements in model in the given order

SerdIter *serd_model_find(const SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Search for statements by a quad pattern.

Returns

An iterator to the first match, or NULL if no matches found.

SerdRange *serd_model_range(const SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Search for statements by a quad pattern.

Returns

A range containing all matching statements.

const SerdNode *serd_model_get(const SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Search for a single node that matches a pattern.

Exactly one of s, p, o must be NULL. This function is mainly useful for predicates that only have one value.

Returns

The first matching node, or NULL if no matches are found.

const SerdStatement *serd_model_get_statement(const SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Search for a single statement that matches a pattern.

This function is mainly useful for predicates that only have one value.

Returns

The first matching statement, or NULL if none are found.

bool serd_model_ask(const SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Return true iff a statement exists.

size_t serd_model_count(const SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Return the number of matching statements.

SerdStatus serd_model_add(SerdModel *model, const SerdNode *s, const SerdNode *p, const SerdNode *o, const SerdNode *g)

Add a statement to a model from nodes.

This function fails if there are any active iterators on model.

SerdStatus serd_model_insert(SerdModel *model, const SerdStatement *statement)

Add a statement to a model.

This function fails if there are any active iterators on model. If statement is null, then SERD_FAILURE is returned.

SerdStatus serd_model_add_range(SerdModel *model, SerdRange *range)

Add a range of statements to a model.

This function fails if there are any active iterators on model.

SerdStatus serd_model_erase(SerdModel *model, SerdIter *iter)

Remove a statement from a model via an iterator.

Calling this function invalidates all iterators on model except iter.

Parameters
  • model – The model which iter points to.

  • iter – Iterator to the element to erase, which is incremented to the next value on return.

SerdStatus serd_model_erase_range(SerdModel *model, SerdRange *range)

Remove a range from a model.

Calling this function invalidates all iterators on model.

Parameters
  • model – The model which range points to.

  • range – Range to erase, which will be empty on return.

SerdStatus serd_model_clear(SerdModel *model)

Remove everything from a model.

Calling this function invalidates all iterators on model.

Parameters

model – The model to clear.

SerdStatus serd_validate_model(SerdValidator *const validator, const SerdModel *model, const SerdNode *graph)

Validate model.

This performs validation based on the XSD, RDF, RDFS, and OWL vocabularies. All necessary data, including those vocabularies and any property/class definitions that use them, are assumed to be in model.

Validation errors are reported to the world’s error sink.

Parameters
  • validator – Validator configured to run the desired checks.

  • model – The model to run the validator on.

  • graph – Optional graph to check. Is this is non-null, then top-level checks will be initiated only by statements in the given graph. The entire model is still searched while running a check so that, for example, schemas that define classes and properties can be stored in separate graphs. If this is null, then the validator simply ignores graphs and searches the entire model for everything.

Returns

SERD_SUCCESS if no errors are found, or SERD_ERR_INVALID if validation checks failed.

Inserter

SerdSink *serd_inserter_new(SerdModel *model, const SerdNode *default_graph)

Create an inserter for writing statements to a model.

struct SerdBuffer

A mutable buffer in memory

void *buf

Buffer.

size_t len

Size of buffer in bytes.

void serd_free(void *ptr)

Free memory allocated by Serd.

This function exists because some systems require memory allocated by a library to be freed by code in the same library. It is otherwise equivalent to the standard C free() function.

Serd C++ API

Serd C++ API details

Internal C++ wrapper details that should not be used directly by clients.

template<class T, Mutable<T> *Copy, bool Equals, void Free>
class BasicCopyable

Generic wrapper for a “basic” copyable object.

This wraps objects with simple ownership semantics where a const pointer is never owned, and a mutable pointer is owned. This has no space overhead compared to a raw pointer since the ownership is encoded in the type.

using Deleter = BasicDeleter<T, Free>
using Base = Wrapper<T, Deleter>
BasicCopyable(T *ptr)
BasicCopyable(const BasicCopyable &wrapper)
template<class U, void UFree>
BasicCopyable(const BasicCopyable<U, Copy, Equals, UFree> &wrapper)
BasicCopyable(BasicCopyable&&) noexcept = default
~BasicCopyable() noexcept = default
BasicCopyable &operator=(BasicCopyable&&) noexcept = default
BasicCopyable &operator=(const BasicCopyable &wrapper)
template<class U>
bool operator==(const BasicCopyable<U, Copy, Equals, Free> &wrapper) const
template<class U>
bool operator!=(const BasicCopyable<U, Copy, Equals, Free> &wrapper) const
template<class T, Mutable<T> *Copy, bool Equals, void Free>
class DynamicCopyable

Wrapper for a “dynamic” copyable C object.

This wraps objects that require dynamic tracking of the ownership.

using Deleter = DynamicDeleter<T, Free>
using Base = Wrapper<T, Deleter>
DynamicCopyable(std::unique_ptr<T, Deleter> ptr)
DynamicCopyable(const DynamicCopyable &wrapper)
DynamicCopyable(DynamicCopyable&&) noexcept = default
DynamicCopyable &operator=(DynamicCopyable&&) noexcept = default
~DynamicCopyable() noexcept = default
DynamicCopyable &operator=(const DynamicCopyable &wrapper)
template<class U>
bool operator==(const DynamicCopyable<U, Copy, Equals, Free> &wrapper) const
template<class U>
bool operator!=(const DynamicCopyable<U, Copy, Equals, Free> &wrapper) const
DynamicCopyable(std::nullptr_t)
template<class T, void Free>
struct BasicDeleter

Simple overhead-free deleter for a C object.

Can be used with const or mutable pointers, but only mutable pointers will be freed. This makes it simple to wrap APIs where constness conveys ownership, but can not handle unowned mutable pointers.

template<class>
void operator()(Mutable<T> *ptr)
template<class>
void operator()(const T*)
template<class T, void Free>
struct DynamicDeleter

Deleter for a C object that can handle dynamic ownership.

Unlike BasicDeleter, this can be used to handle non-owned references to mutable objects, at the cost of an extra word for tracking the ownership (since constness in the type can’t convey this information).

DynamicDeleter(Ownership ownership)
void operator()(T *ptr)
template<class T, class Deleter>
class Wrapper

Generic C++ wrapper for a C object.

using CType = T
std::unique_ptr<T, Deleter> _ptr
Wrapper(T *ptr)
Wrapper(T *ptr, Deleter deleter)
Wrapper(std::unique_ptr<T, Deleter> ptr)
Wrapper(Wrapper&&) noexcept = default
Wrapper &operator=(Wrapper&&) noexcept = default
Wrapper(const Wrapper&) = delete
Wrapper &operator=(const Wrapper&) = delete
~Wrapper() = default
T *cobj()

Return a pointer to the underlying C object.

const T *cobj() const

Return a pointer to the underlying C object.

Wrapper(std::nullptr_t)
void reset()
enum class Ownership

Ownership for DynamicDeleter

enumerator owned

This pointer owns the data and must delete it.

enumerator view

This pointer is just a view and must not delete the data.

template<class T>
using CopyFunc = T *(*)(const T*)

Copy function for a C object.

template<class T>
using Mutable = typename std::remove_const_t<T>

Utility template for a mutable type which removes const if necessary.

Flags

template<typename Flag>
class Flags

Type-safe bit flags.

This is a minimal interface for type-safe bit flags, which only allows values from the corresponding flags enum to be set. It functions like a normal unsigned integer bit field, but attempting to get or set a flag with the incorrect type will fail to compile.

Parameters

Flag – Strong enumeration type for flag values.

using FlagUnderlyingType = typename std::underlying_type<Flag>::type
using Value = typename std::make_unsigned<FlagUnderlyingType>::type
constexpr Flags() noexcept
constexpr Flags(const Value value) noexcept
constexpr Flags(const Flag f) noexcept
constexpr Flags operator|(const Flag rhs) const noexcept

Set a flag.

constexpr Flags operator|(const Flags rhs) const noexcept

Set all the flags from another set of flags.

constexpr bool operator==(const Flag rhs) const noexcept
constexpr operator Value() const noexcept
template<typename Flag>
constexpr std::enable_if_t<std::is_enum<Flag>::value, Flags<Flag>> operator|(const Flag lhs, const Flag rhs) noexcept

Make a new Flags by combining two individual flags.

Optional

struct Nullopt

Special tag for constructing an unset Optional.

enum class Construct
constexpr Nullopt(Construct)
template<typename T>
class Optional

A simple optional wrapper around a wrapped type with a pointer-like API.

This works like a typical optional type, but only works with Wrapper types, and exploits the fact that these are interally just pointers to avoid adding space overhead for an “is_set” flag, like a generic optional class would.

Types must explicitly opt-in to being optional by providing a constructor that takes a single ContructNullOptional argument. This constructor should only be used by the Optional implementation, which guarantees that such an object will not be used except by calling its cobj() method.

using CType = typename T::CType

The type of the underlying C object.

Optional()

Constructs an empty optional.

Optional(Nullopt)

Constructs an empty optional.

Optional(T value)
template<typename U, typename>
Optional(U &&value)
void reset()

Destroys any contained value.

const T &operator*() const

Accesses the contained value.

T &operator*()

Accesses the contained value.

const T *operator->() const

Accesses the contained value.

T *operator->()

Accesses the contained value.

bool operator==(const Optional &optional)

Tests if optional objects are equal.

bool operator!=(const Optional &optional)

Tests if optional objects are not equal.

operator bool() const
bool operator!() const
CType *cobj()
const CType *cobj() const

Status Codes

enum class Status

Return status code.

enumerator success

No error.

enumerator failure

Non-fatal failure.

enumerator err_unknown

Unknown error.

enumerator err_bad_syntax

Invalid syntax.

enumerator err_bad_arg

Invalid argument.

enumerator err_bad_iter

Use of invalidated iterator.

enumerator err_not_found

Not found.

enumerator err_id_clash

Encountered clashing blank node IDs.

enumerator err_bad_curie

Invalid CURIE (e.g. prefix does not exist)

enumerator err_internal

Unexpected internal error (should not happen)

enumerator err_overflow

Stack overflow.

enumerator err_invalid

Invalid data.

enumerator err_no_data

Unexpected end of input.

enumerator err_bad_write

Error writing to file/stream.

enumerator err_bad_call

Invalid call.

const char *strerror(const Status status)

Return a string describing a status code.

String Utilities

template<class Container>
std::string base64_encode(const Container &buf)

Encode size bytes of buf into str, which must be large enough.

Parameters

buf – Input binary data (vector-like container of bytes).

Returns

A base64 encoded representation of the data in buf.

Syntax Utilities

enum class Syntax

Syntax supported by serd.

enumerator empty

Empty syntax (suppress input or output)

enumerator Turtle

Terse triples http://www.w3.org/TR/turtle.

enumerator NTriples

Flat triples http://www.w3.org/TR/n-triples/.

enumerator NQuads

Flat quads http://www.w3.org/TR/n-quads/.

enumerator TriG

Terse quads http://www.w3.org/TR/trig/.

Syntax syntax_by_name(StringView name)

Get a syntax by name.

Case-insensitive, supports “Turtle”, “NTriples”, “NQuads”, and “TriG”. SERD_SYNTAX_EMPTY is returned if the name is not recognized.

Syntax guess_syntax(StringView filename)

Guess a syntax from a filename.

This uses the file extension to guess the syntax of a file. SERD_SYNTAX_EMPTY is returned if the extension is not recognized.

bool syntax_has_graphs(const Syntax syntax)

Return whether a syntax can represent multiple graphs.

Returns

True for SERD_NQUADS and SERD_TRIG, false otherwise.

Data

URI

class URI

A parsed URI.

This directly refers to slices in other strings, it does not own any memory itself. Thus, URIs can be parsed and/or resolved against a base URI in-place without allocating memory.

using Component = StringView

Component of a URI.

Note that there is a distinction between a component being non-present and present but empty. For example, “file:///path” has an empty authority, while “file:/path” has no authority. A non-present component has its data() pointer set to null, while an empty component has a data pointer, but length zero.

URI(StringView str)

Construct a URI by parsing a URI string.

URI(const SerdURIView &uri)

Construct a URI from a C URI view.

Component scheme() const

Return the scheme of this URI.

Component authority() const

Return the authority of this URI.

Component path_prefix() const

Return the path prefix of this URI, which is set if it has been resolved.

Component path() const

Return the path (suffix) of this URI.

Component query() const

Return the query.

Component fragment() const

Return the fragment of this URI.

URI resolve(const URI &base) const

Return this URI resolved against base

std::string string() const

Return URI as a string.

std::string relative_string(const URI &base) const

Return this URI as a string relative to base

std::string relative_string(const URI &base, const URI &root) const

Return this URI as a string relative to base but constrained to root.

The returned URI string is relative iff this URI is a child of both base and root. The root must be a prefix of base and can be used keep up-references (“../”) within a certain namespace.

const SerdURIView *cobj() const

Return a pointer to the underlying C object.

std::string parse_file_uri(StringView uri, std::string *hostname = nullptr)

Get the unescaped path and hostname from a file URI.

The returned path and *hostname must be freed with serd_free().

Parameters
  • uri – A file URI.

  • hostname – If non-NULL, set to the hostname, if present.

Returns

A filesystem path.

bool uri_string_has_scheme(StringView string)

Return true iff string starts with a valid URI scheme.

Node

template<class CObj>
class NodeWrapper

Node wrapper.

NodeWrapper(CObj *ptr)
template<class C>
NodeWrapper(const NodeWrapper<C> &node)
NodeWrapper(const bool b)
NodeWrapper(const double d)
NodeWrapper(const float f)
NodeWrapper(const int64_t i)
NodeType type() const
const char *c_str() const
StringView str() const
size_t size() const
size_t length() const
Optional<NodeView> datatype() const

Return the datatype of a literal node if present.

Optional<NodeView> language() const

Return the language of a literal node if present.

SerdURIView uri_view() const

Return a parsed view of the URI in a node.

It is best to check the node type before calling this function, though it is safe to call on non-URI nodes. In that case, it will return a null view with all fields zero.

Note that this parses the URI string contained in the node, so it is a good idea to keep the value if you will be using it several times in the same scope.

Node resolve(NodeView base) const
bool operator<(NodeView node) const
operator std::string() const
operator StringView() const
operator SerdStringView() const
const char *begin() const
const char *end() const
bool empty() const
enum class NodeType

Type of a node.

An RDF node, in the abstract sense, can be either a resource, literal, or a blank. This type is more precise, because syntactically there are two ways to refer to a resource (by URI or CURIE). Serd also has support for variable nodes to support some features, which are not RDF nodes.

There are also two ways to refer to a blank node in syntax (by ID or anonymously), but this is handled by statement flags rather than distinct node types.

enumerator literal

Literal value.

A literal optionally has either a language, or a datatype (not both).

enumerator URI

URI (absolute or relative).

Value is an unquoted URI string, which is either a relative reference with respect to the current base URI (e.g. “foo/bar”), or an absolute URI (e.g. “http://example.org/foo”). RFC3986

enumerator CURIE

CURIE, a shortened URI.

Value is an unquoted CURIE string relative to the current environment, e.g. “rdf:type”. CURIE Syntax 1.0

enumerator blank

A blank node.

Value is a blank node ID without any syntactic prefix, like “id3”, which is meaningful only within this serialisation. RDF 1.1 Turtle

using Node = NodeWrapper<SerdNode>

A mutable node.

using NodeView = NodeWrapper<const SerdNode>

A view of an immutable node.

Node make_string(StringView str)

Create a new plain literal node with no language from str

Node make_plain_literal(StringView str, StringView lang)

Create a new plain literal node from str with lang.

A plain literal has no datatype, but may have a language tag. The lang may be empty, in which case this is equivalent to serd_new_string().

Node make_typed_literal(StringView str, const StringView datatype)

Create a new typed literal node from str

Node make_blank(StringView str)

Create a new blank node.

Node make_curie(StringView str)

Create a new CURIE node.

Node make_uri(URI uri)

Create a new URI from a URI view.

Node make_file_uri(StringView path, StringView hostname)

Create a new file URI node from a file system path and optional hostname.

Backslashes in Windows paths will be converted, and other characters will be percent encoded as necessary.

If path is relative, hostname is ignored.

Node make_boolean(const bool b)

Create a new node by serialising b into an xsd:boolean string.

Node make_decimal(double d, Optional<NodeView> datatype = {})

Create a new canonical xsd:decimal literal.

The resulting node will always contain a ‘.’, start with a digit, and end with a digit (a leading and/or trailing ‘0’ will be added if necessary), for example, “1.0”. It will never be in scientific notation.

Parameters
  • d – The value for the new node.

  • datatype – Datatype of node, or NULL for xsd:decimal.

Node make_double(double d)

Create a new canonical xsd:double literal.

The returned node will always be in scientific notation, like “1.23E4”, except for NaN and negative/positive infinity, which are “NaN”, “-INF”, and “INF”, respectively.

Uses the shortest possible representation that precisely describes d, which has at most 17 significant digits (under 24 characters total).

Parameters

d – Double value to write.

Returns

A literal node with datatype xsd:double.

Node make_float(float f)

Create a new canonical xsd:float literal.

Uses identical formatting to serd_new_double(), except with at most 9 significant digits (under 14 characters total).

Parameters

f – Float value of literal.

Returns

A literal node with datatype xsd:float.

Node make_integer(int64_t i, Optional<NodeView> datatype = {})

Create a new canonical xsd:integer literal.

Parameters
  • i – Integer value of literal.

  • datatype – Datatype of node, or NULL for xsd:integer.

Node make_base64(const void *buf, size_t size)

Create a new canonical xsd:base64Binary literal.

This function can be used to make a node out of arbitrary binary data, which can be decoded using base64_decode().

Parameters
  • buf – Raw binary data to encode in node.

  • size – Size of buf in bytes.

template<class T>
T get(NodeView node)

Prototype for Node get() templates.

template<>
bool get<bool>(NodeView node)

Return the value of node as a boolean.

This will work for booleans, and numbers of any datatype if they are 0 or 1.

Returns

The value of node as a bool, or false on error.

template<>
double get<double>(NodeView node)

Return the value of node as a double.

This will coerce numbers of any datatype to double, if the value fits.

Returns

The value of node as a double, or NaN on error.

template<>
float get<float>(NodeView node)

Return the value of node as a float.

This will coerce numbers of any datatype to float, if the value fits.

Returns

The value of node as a float, or NaN on error.

template<>
int64_t get<int64_t>(NodeView node)

Return the value of node as a long (signed 64-bit integer).

This will coerce numbers of any datatype to long, if the value fits.

Returns

The value of node as a int64_t, or 0 on error.

Optional<NodeView> datatype() const

Return the datatype of a literal node if present.

Optional<NodeView> language() const

Return the language of a literal node if present.

Nodes

Cursor

template<class CObj>
class CursorWrapper

Cursor wrapper.

CursorWrapper(CObj *cursor)
template<class C>
CursorWrapper(const CursorWrapper<C> &cursor)
NodeView name() const

Return the document name.

This is typically a file URI, but may be a descriptive string node for statements that originate from streams.

unsigned line() const

Return the one-relative line number in the document.

unsigned column() const

Return the zero-relative column number in the line.

struct CursorData

Extra data managed by mutable (user created) Cursor.

Node name_node
class Cursor

The origin of a statement in a document.

Cursor(NodeView name, const unsigned line, const unsigned col)

Create a new cursor.

Parameters
  • name – The name of the document or stream (usually a file URI)

  • line – The line number in the document (1-based)

  • col – The column number in the document (1-based)

Cursor(const CursorView &cursor)
template<class CObj>
using CursorHandle = detail::BasicCopyable<CObj, serd_cursor_copy, serd_cursor_equals, serd_cursor_free>

Cursor handle.

using CursorView = CursorWrapper<const SerdCursor>

Cursor view.

Statement

template<class CObj>
class StatementWrapper

Statement wrapper.

StatementWrapper(CObj *statement)
template<class C>
StatementWrapper(const StatementWrapper<C> &statement)
NodeView node(Field field) const

Return the given node of the statement.

NodeView subject() const

Return the subject of the statement.

NodeView predicate() const

Return the predicate of the statement.

NodeView object() const

Return the object of the statement.

Optional<NodeView> graph() const

Return the graph of the statement.

Optional<CursorView> cursor() const

Return the source location where the statement originated, or NULL.

bool matches(Optional<NodeView> subject, Optional<NodeView> predicate, Optional<NodeView> object, Optional<NodeView> graph = {}) const

Return true iff the statement matches the given pattern.

Nodes match if they are equivalent, or if one of them is NULL. The statement matches if every node matches.

struct StatementData

Extra data managed by mutable (user created) Statement.

Node _subject
Node _predicate
Node _object
Optional<Node> _graph
Optional<Cursor> _cursor
class Statement

A subject, predicate, and object, with optional graph context.

Statement(const NodeView &s, const NodeView &p, const NodeView &o, const NodeView &g, Optional<CursorView> cursor = {})
Statement(const NodeView &s, const NodeView &p, const NodeView &o, Optional<CursorView> cursor = {})
Statement(const StatementView &statement)
enum class Field

Index of a node in a statement.

enumerator subject

Subject.

enumerator predicate

Predicate (“key”)

enumerator object

Object (“value”)

enumerator graph

Graph (“context”)

using StatementView = StatementWrapper<const SerdStatement>

View of a constant statement.

World

class World

Global library state.

World()
NodeView get_blank()
void set_message_func(LogFunc log_func)
Status log(const LogLevel level, const LogFields &fields, const char *const fmt, ...)
enum class LogLevel

Log message level, compatible with syslog.

enumerator emergency

Emergency, system is unusable.

enumerator alert

Action must be taken immediately.

enumerator critical

Critical condition.

enumerator error

Error.

enumerator warning

Warning.

enumerator notice

Normal but significant condition.

enumerator info

Informational message.

enumerator debug

Debug message.

using LogFields = std::map<StringView, StringView>

Extended fields for a log message.

using LogFunc = std::function<Status(LogLevel, LogFields, std::string&&)>

User-provided callback function for handling a log message.

Data Streaming

Events

enum class StatementFlag

Flags indicating inline abbreviation information for a statement.

enumerator empty_S

Empty blank node subject.

enumerator anon_S

Start of anonymous subject.

enumerator anon_O

Start of anonymous object.

enumerator list_S

Start of list subject.

enumerator list_O

Start of list object.

enumerator terse_S

Start of terse subject.

enumerator terse_O

Start of terse object.

using StatementFlags = Flags<StatementFlag>

Bitwise OR of StatementFlag values.

Sink

template<class CSink>
class SinkWrapper

Sink wrapper.

SinkWrapper(CSink *ptr)
Status base(const NodeView &uri) const

Set the base URI.

Status prefix(NodeView name, const NodeView &uri) const

Set a namespace prefix.

Status statement(StatementFlags flags, StatementView statement) const

Write a statement.

Status write(StatementFlags flags, const NodeView &subject, const NodeView &predicate, const NodeView &object, Optional<NodeView> graph = {}) const

Write a statement from individual nodes.

Status end(const NodeView &node) const

Mark the end of an anonymous node.

class SinkView

Sink view.

SinkView(const SerdSink *ptr)
SinkView(const SinkWrapper<SerdSink> &sink)
class Sink

An interface that receives a stream of RDF data.

Sink()
void set_base_func(BaseFunc base_func)
void set_prefix_func(PrefixFunc prefix_func)
void set_statement_func(StatementFunc statement_func)
void set_end_func(EndFunc end_func)

Canon

class Canon

A sink that transforms literals to canonical form where possible.

The returned sink acts like target in all respects, except literal nodes in statements may be modified from the original.

Canon(const World &world, SinkView target, const CanonFlags flags)
enum class CanonFlag

Flags that control canonical node transformation.

enumerator lax

Tolerate and pass through invalid input.

using CanonFlags = Flags<CanonFlag>

Bitwise OR of SerdCanonFlag values.

Filter

class Filter

A sink that filters out statements that do not match a pattern.

This sink acts like the target sink in all respects, except that some statements may be dropped.

Filter(SinkView target, Optional<NodeView> subject, Optional<NodeView> predicate, Optional<NodeView> object, Optional<NodeView> graph, const bool inclusive)

Construct a filter.

Parameters
  • target – The target sink to pass unfiltered data to.

  • subject – The subject of the filter pattern, or nothing for a wildcard.

  • predicate – The predicate of the filter pattern, or nothing for a wildcard.

  • object – The object of the filter pattern, or nothing for a wildcard.

  • graph – The graph of the filter pattern, or nothing for a wildcard.

  • inclusive – If true, then only statements that match the pattern are passed through. Otherwise, only statements that do not match the pattern are passed through.

Environment

template<class CObj>
class EnvWrapper

Env wrapper.

NodeView base_uri() const

Return the base URI.

Status set_base_uri(const StringView &uri)

Set the base URI.

Status set_prefix(StringView name, StringView uri)

Set a namespace prefix.

Optional<Node> qualify(const NodeView &uri) const

Qualify uri into a CURIE if possible.

Optional<Node> expand(const NodeView &node) const

Expand node into an absolute URI if possible.

void write_prefixes(SinkView sink) const

Send all prefixes to sink

EnvWrapper(std::unique_ptr<CObj> ptr)
EnvWrapper(CObj *const ptr)
class Env

Lexical environment for relative URIs or CURIEs (base URI and namespaces)

Env()
Env(const NodeView &base)
using EnvView = EnvWrapper<const SerdEnv>

EnvView.

Reading and Writing

Byte Source

class ByteSource

A source for bytes that provides text input.

ByteSource(std::istream &stream)
ByteSource(const std::string &string)
ByteSource(const ByteSource&) = delete
ByteSource &operator=(const ByteSource&) = delete
ByteSource(ByteSource&&) = delete
ByteSource &operator=(ByteSource&&) = delete
~ByteSource() = default
size_t s_read(void *buf, size_t size, size_t nmemb, void *source) noexcept
int s_error(void *source) noexcept

Reader

class Reader

Streaming parser that reads a text stream and writes to a statement sink.

Reader(World &world, const Syntax syntax, const ReaderFlags flags, Env &env, SinkView sink, size_t stack_size)
void add_blank_prefix(StringView prefix)
Status start(ByteSource &byte_source)
Status read_chunk()
Status read_document()
Status finish()
enum class ReaderFlag

Reader options.

enumerator lax

Tolerate invalid input where possible.

using ReaderFlags = Flags<ReaderFlag>

Bitwise OR of SerdReaderFlag values.

Byte Sink

class ByteSink

A sink for bytes that receives text output.

ByteSink(WriteFunc write_func, const size_t block_size)

Create a byte sink that writes to a function in blocks.

ByteSink(StringView filename, const size_t block_size)
ByteSink(WriteFunc write_func)

Create a byte sink that writes to a function one byte at a time.

ByteSink(std::ostream &stream)

Create a byte sink from a standard output stream.

Status close()
using WriteFunc = std::function<size_t(const char*, size_t)>

Sink function for string output.

Similar semantics to SerdWriteFunc (and in turn fwrite), but takes char* for convenience and may set errno for more informative error reporting than supported by SerdStreamErrorFunc.

Returns

Number of elements (bytes) written, which is short on error.

Writer

class Writer

Streaming writer that writes a text stream as it receives events.

Writer(World &world, const Syntax syntax, const WriterFlags flags, Env &env, ByteSink sink)

Create a writer that writes syntax to the given byte sink.

Writer(World &world, const Syntax syntax, const WriterFlags flags, Env &env, WriteFunc write_func)

Convenience overload that writes to a function.

Writer(World &world, const Syntax syntax, const WriterFlags flags, Env &env, std::ostream &stream)

Convenience overload that writes to a standard output stream.

SinkView sink()

Return a sink that can be used to write data.

Status set_root_uri(const NodeView &uri)
Status finish()
enum class WriterFlag

Writer style options.

These flags allow more precise control of writer output style. Note that some options are only supported for some syntaxes, for example, NTriples does not support abbreviation and is always ASCII.

enumerator ascii

Escape all non-ASCII characters.

enumerator terse

Write terser output without newlines.

enumerator lax

Tolerate lossy output.

using WriterFlags = Flags<WriterFlag>

Bitwise OR of SerdWriterFlag values.

Storage

Iterator

class Iter

An iterator that points to a statement in a model.

Iter(IterView iter)
Iter(SerdIter *const ptr, const detail::Ownership ownership)
Iter(Iter&&) = default
Iter(const Iter&) = default
Iter &operator=(Iter&&) = default
Iter &operator=(const Iter&) = default
~Iter() = default
Iter &operator++()

Range

class Range

A range of statements in a model.

const Iter &begin() const

Return an iterator to the first element in the range.

Iter &begin()

Return an iterator one past the last element in the range.

const Iter &end() const

Return an iterator one past the last element in the range.

Status write(SinkView sink, SerialisationFlags flags = {})

Write range to sink.

The serialisation style can be controlled with flags. The default is to write statements in an order suited for pretty-printing with Turtle or TriG with as many objects written inline as possible. If SERD_NO_INLINE_OBJECTS is given, a simple sorted stream is written instead, which is significantly faster since no searching is required, but can result in ugly output for Turtle or Trig.

bool empty() const

Return true iff there are no statements in range

enum class SerialisationFlag

Flags that control the style of a model serialisation.

enumerator no_inline_objects

Disable object inlining.

using SerialisationFlags = Flags<SerialisationFlag>

Bitwise OR of SerialisationFlag values.

Model

class Model

An indexed set of statements.

using value_type = Statement
using iterator = Iter
using const_iterator = Iter
Model(World &world, ModelFlags flags)
size_t size() const

Return the number of statements stored in model

bool empty() const

Return true iff there are no statements stored in model

Status insert(StatementView s)

Add a statement to a model.

This function fails if there are any active iterators on model. If statement is null, then SERD_FAILURE is returned.

Status insert(const NodeView &s, const NodeView &p, const NodeView &o, Optional<NodeView> g = {})

Add a statement to a model from nodes.

This function fails if there are any active iterators on model.

Status insert(Range &&range)

Add a range of statements to a model.

This function fails if there are any active iterators on model.

Iter erase(Iter iter)

Remove a statement from a model via an iterator.

Calling this function invalidates all iterators on model except iter.

Parameters

iter – Iterator to the element to erase.

Returns

An iterator to the statement following the erased statement, or the end iterator if the statement was the last or an error occurred.

Iter erase(IterView iter)
Status erase(Range range)

Remove a range from a model.

Calling this function invalidates all iterators on model except iter.

Parameters

range – Range to erase.

Iter find(Optional<NodeView> s, Optional<NodeView> p, Optional<NodeView> o, Optional<NodeView> g = {}) const

Search for statements by a quad pattern.

Returns

An iterator to the first match, or NULL if no matches found.

Range range(Optional<NodeView> s, Optional<NodeView> p, Optional<NodeView> o, Optional<NodeView> g = {}) const

Search for statements by a quad pattern.

Returns

A range containing all matching statements.

Optional<NodeView> get(Optional<NodeView> s, Optional<NodeView> p, Optional<NodeView> o, Optional<NodeView> g = {}) const

Search for a single node that matches a pattern.

Exactly one of s, p, o must be NULL. This function is mainly useful for predicates that only have one value.

Returns

The first matching node, or NULL if no matches are found.

Optional<StatementView> get_statement(Optional<NodeView> s, Optional<NodeView> p, Optional<NodeView> o, Optional<NodeView> g = {}) const

Search for a single statement that matches a pattern.

This function is mainly useful for predicates that only have one value.

Returns

The first matching statement, or NULL if none are found.

bool ask(Optional<NodeView> s, Optional<NodeView> p, Optional<NodeView> o, Optional<NodeView> g = {}) const

Return true iff a statement exists.

size_t count(Optional<NodeView> s, Optional<NodeView> p, Optional<NodeView> o, Optional<NodeView> g = {}) const

Return the number of matching statements.

Range all() const

Return a range of all statements in model in SPO order.

Range ordered(StatementOrder order) const

Return a range of all statements in model in the given order

iterator begin() const
iterator end() const
enum class ModelFlag

Flags that control model storage and indexing.

enumerator index_SPO

Subject, Predicate, Object.

enumerator index_SOP

Subject, Object, Predicate.

enumerator index_OPS

Object, Predicate, Subject.

enumerator index_OSP

Object, Subject, Predicate.

enumerator index_PSO

Predicate, Subject, Object.

enumerator index_POS

Predicate, Object, Subject.

enumerator index_graphs

Support multiple graphs in model.

enumerator store_cursors

Store original cursor of statements.

enum class StatementOrder

Statement ordering.

Statements themselves always have the same fields in the same order (subject, predicate, object, graph), but a model can keep indices for different orderings to provide good performance for different kinds of queries.

enumerator SPO

Subject, Predicate, Object.

enumerator SOP

Subject, Object, Predicate.

enumerator OPS

Object, Predicate, Subject.

enumerator OSP

Object, Subject, Predicate.

enumerator PSO

Predicate, Subject, Object.

enumerator POS

Predicate, Object, Subject.

enumerator GSPO

Graph, Subject, Predicate, Object.

enumerator GSOP

Graph, Subject, Object, Predicate.

enumerator GOPS

Graph, Object, Predicate, Subject.

enumerator GOSP

Graph, Object, Subject, Predicate.

enumerator GPSO

Graph, Predicate, Subject, Object.

enumerator GPOS

Graph, Predicate, Object, Subject.

using ModelFlags = Flags<ModelFlag>

Bitwise OR of ModelFlag values.

Inserter

class Inserter

Model inserter.

Inserter(Model &model)
Inserter(Model &model, Optional<NodeView> default_graph)

String View

class StringView

Immutable slice of a string.

This is a minimal implementation that is compatible with std::string_view and std::string for most basic use cases. This could be replaced with std::string_view once C++17 support can be relied on.

using char_type = char
using size_type = size_t
using traits_type = std::char_traits<char>
using value_type = char
using pointer = value_type*
using const_pointer = const value_type*
using reference = value_type&
using const_reference = const value_type&
using iterator = const char*
using const_iterator = const char*
constexpr size_type npos
constexpr StringView() noexcept = default
constexpr StringView(const char *const str, const size_t len) noexcept
StringView(const char *const str) noexcept
StringView(const std::string &str) noexcept
constexpr size_t size() const
constexpr size_t length() const
constexpr bool empty() const
constexpr const char *c_str() const
constexpr const char *data() const
constexpr const char &front() const
constexpr const char &back() const
constexpr const_iterator begin() const
constexpr const_iterator end() const
constexpr const_iterator cbegin() const
constexpr const_iterator cend() const
constexpr const char &operator[](const size_t pos) const
const char &at(const size_t pos) const
StringView substr(const size_t pos) const
StringView substr(const size_t pos, const size_t n) const
int compare(StringView rhs) const noexcept
template<class Alloc>
std::basic_string<char, traits_type, Alloc> str() const
template<class Alloc>
std::basic_string<char, traits_type, Alloc> str(const Alloc &alloc) const
operator std::string() const
operator const char*() const
operator SerdStringView() const