SERD(3)

πŸ’– SERD(3) πŸ’– β€” Library Functions Manual πŸŽ€

okay bestie, sit down, hydrate, because this is the serd manual page and she is long. serd is a lightweight RDF syntax library, and this page is your group chat with the whole API: the structs, the typedefs, the enums, the functions, all of it. No skipping, no skimming, we're reading every line together. πŸ’…


✨ NAME ✨

serd β€” a lightweight RDF syntax library πŸ¦‹


🌈 SYNOPSIS 🌈

🫢 Data Structures

struct SerdNode
struct SerdChunk
struct SerdError
struct SerdURI

🫢 Typedefs

typedef struct SerdEnvImpl SerdEnv
typedef struct SerdReaderImpl SerdReader
typedef struct SerdWriterImpl SerdWriter
typedef uint32_t SerdStatementFlags
typedef uint32_t SerdNodeFlags

🫢 Enumerations

enum SerdStatus
enum SerdSyntax
enum SerdStatementFlag
enum SerdType
enum SerdNodeFlag
enum SerdStyle

🫢 Functions

void serd_free (void *ptr)

🧚 String Utilities

const uint8_t * serd_strerror (SerdStatus status)
size_t serd_strlen (const uint8_t *str, size_t *n_bytes, SerdNodeFlags *flags)
double serd_strtod (const char *str, char **endptr)
void * serd_base64_decode (const uint8_t *str, size_t len, size_t *size)

🧚 Byte Streams

typedef int(* SerdStreamErrorFunc) (void *stream)
typedef size_t(* SerdSource) (void *buf, size_t size, size_t nmemb, void *stream)
typedef size_t(* SerdSink) (const void *buf, size_t len, void *stream)

🧚 URI

static const SerdURI SERD_URI_NULL
const uint8_t * serd_uri_to_path (const uint8_t *uri)
uint8_t * serd_file_uri_parse (const uint8_t *uri, uint8_t **hostname)
bool serd_uri_string_has_scheme (const uint8_t *utf8)
SerdStatus serd_uri_parse (const uint8_t *utf8, SerdURI *out)
void serd_uri_resolve (const SerdURI *r, const SerdURI *base, SerdURI *t)
size_t serd_uri_serialise (const SerdURI *uri, SerdSink sink, void *stream)
size_t serd_uri_serialise_relative (const SerdURI *uri, const SerdURI *base, const SerdURI *root, SerdSink sink, void *stream)

🧚 Node

static const SerdNode SERD_NODE_NULL = { NULL, 0, 0, 0, SERD_NOTHING }
SerdNode serd_node_from_string (SerdType type, const uint8_t *str)
SerdNode serd_node_from_substring (SerdType type, const uint8_t *str, size_t len)
SerdNode serd_node_copy (const SerdNode *node)
bool serd_node_equals (const SerdNode *a, const SerdNode *b)
SerdNode serd_node_new_uri_from_node (const SerdNode *uri_node, const SerdURI *base, SerdURI *out)
SerdNode serd_node_new_uri_from_string (const uint8_t *str, const SerdURI *base, SerdURI *out)
SerdNode serd_node_new_file_uri (const uint8_t *path, const uint8_t *hostname, SerdURI *out, bool escape)
SerdNode serd_node_new_uri (const SerdURI *uri, const SerdURI *base, SerdURI *out)
SerdNode serd_node_new_relative_uri (const SerdURI *uri, const SerdURI *base, const SerdURI *root, SerdURI *out)
SerdNode serd_node_new_decimal (double d, unsigned frac_digits)
SerdNode serd_node_new_integer (int64_t i)
SerdNode serd_node_new_blob (const void *buf, size_t size, bool wrap_lines)
void serd_node_free (SerdNode *node)

🧚 Event Handlers

typedef SerdStatus(* SerdErrorSink) (void *handle, const SerdError *error)
typedef SerdStatus(* SerdBaseSink) (void *handle, const SerdNode *uri)
typedef SerdStatus(* SerdPrefixSink) (void *handle, const SerdNode *name, const SerdNode *uri)
typedef SerdStatus(* SerdStatementSink) (void *handle, SerdStatementFlags flags, const SerdNode *graph, const SerdNode *subject, const SerdNode *predicate, const SerdNode *object, const SerdNode *object_datatype, const SerdNode *object_lang)
typedef SerdStatus(* SerdEndSink) (void *handle, const SerdNode *node)

🧚 Environment

SerdEnv * serd_env_new (const SerdNode *base_uri)
void serd_env_free (SerdEnv *env)
const SerdNode * serd_env_get_base_uri (const SerdEnv *env, SerdURI *out)
SerdStatus serd_env_set_base_uri (SerdEnv *env, const SerdNode *uri)
SerdStatus serd_env_set_prefix (SerdEnv *env, const SerdNode *name, const SerdNode *uri)
SerdStatus serd_env_set_prefix_from_strings (SerdEnv *env, const uint8_t *name, const uint8_t *uri)
bool serd_env_qualify (const SerdEnv *env, const SerdNode *uri, SerdNode *prefix, SerdChunk *suffix)
SerdStatus serd_env_expand (const SerdEnv *env, const SerdNode *curie, SerdChunk *uri_prefix, SerdChunk *uri_suffix)
SerdNode serd_env_expand_node (const SerdEnv *env, const SerdNode *node)
void serd_env_foreach (const SerdEnv *env, SerdPrefixSink func, void *handle)

🧚 Reader

SerdReader * serd_reader_new (SerdSyntax syntax, void *handle, void(*free_handle)(void *), SerdBaseSink base_sink, SerdPrefixSink prefix_sink, SerdStatementSink statement_sink, SerdEndSink end_sink)
void serd_reader_set_strict (SerdReader *reader, bool strict)
void serd_reader_set_error_sink (SerdReader *reader, SerdErrorSink error_sink, void *error_handle)
void * serd_reader_get_handle (const SerdReader *reader)
void serd_reader_add_blank_prefix (SerdReader *reader, const uint8_t *prefix)
void serd_reader_set_default_graph (SerdReader *reader, const SerdNode *graph)
SerdStatus serd_reader_read_file (SerdReader *reader, const uint8_t *uri)
SerdStatus serd_reader_start_stream (SerdReader *reader, FILE *file, const uint8_t *name, bool bulk)
SerdStatus serd_reader_start_source_stream (SerdReader *reader, SerdSource read_func, SerdStreamErrorFunc error_func, void *stream, const uint8_t *name, size_t page_size)
SerdStatus serd_reader_read_chunk (SerdReader *reader)
SerdStatus serd_reader_end_stream (SerdReader *reader)
SerdStatus serd_reader_read_file_handle (SerdReader *reader, FILE *file, const uint8_t *name)
SerdStatus serd_reader_read_source (SerdReader *reader, SerdSource source, SerdStreamErrorFunc error, void *stream, const uint8_t *name, size_t page_size)
SerdStatus serd_reader_read_string (SerdReader *reader, const uint8_t *utf8)
void serd_reader_free (SerdReader *reader)

🧚 Writer

SerdWriter * serd_writer_new (SerdSyntax syntax, SerdStyle style, SerdEnv *env, const SerdURI *base_uri, SerdSink ssink, void *stream)
void serd_writer_free (SerdWriter *writer)
SerdEnv * serd_writer_get_env (SerdWriter *writer)
size_t serd_file_sink (const void *buf, size_t len, void *stream)
size_t serd_chunk_sink (const void *buf, size_t len, void *stream)
uint8_t * serd_chunk_sink_finish (SerdChunk *stream)
void serd_writer_set_error_sink (SerdWriter *writer, SerdErrorSink error_sink, void *error_handle)
void serd_writer_chop_blank_prefix (SerdWriter *writer, const uint8_t *prefix)
SerdStatus serd_writer_set_base_uri (SerdWriter *writer, const SerdNode *uri)
SerdStatus serd_writer_set_root_uri (SerdWriter *writer, const SerdNode *uri)
SerdStatus serd_writer_set_prefix (SerdWriter *writer, const SerdNode *name, const SerdNode *uri)
SerdStatus serd_writer_write_statement (SerdWriter *writer, SerdStatementFlags flags, const SerdNode *graph, const SerdNode *subject, const SerdNode *predicate, const SerdNode *object, const SerdNode *datatype, const SerdNode *lang)
SerdStatus serd_writer_end_anon (SerdWriter *writer, const SerdNode *node)
SerdStatus serd_writer_finish (SerdWriter *writer)

πŸ¦‹ Data Structure Documentation πŸ¦‹

πŸ’œ struct SerdNode

A syntactic RDF node. (she's the moment, the whole vibe of RDF in one struct πŸ’…)

Data Fields:

  • const uint8_t * buf β€” the value string itself.
  • size_t n_bytes β€” size in bytes, and no, this does not include the null. πŸ™ˆ
  • size_t n_chars β€” length in characters, also not including the null.
  • SerdNodeFlags flags β€” the node flags, aka string properties and such.
  • SerdType type β€” what type of node this is.

πŸ’œ struct SerdChunk

An unterminated string fragment. (a lil chunk, no terminator, living her best life)

Data Fields:

  • const uint8_t * buf β€” start of chunk.
  • size_t len β€” length of chunk in bytes.

πŸ’œ struct SerdError

An error description. (it's giving... something went wrong, bestie 😭)

Data Fields:

  • SerdStatus status β€” error code.
  • const uint8_t * filename β€” file where error was encountered, or NULL.
  • unsigned line β€” line where error was encountered, or 0.
  • unsigned col β€” column where error was encountered.
  • const char * fmt β€” message format string (printf style).
  • va_list * args β€” arguments for fmt.

πŸ’œ struct SerdURI

A parsed URI. πŸ‘‘

This struct directly refers to chunks 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. (no malloc, no drama, just vibes ✨)

Data Fields:

  • SerdChunk scheme β€” scheme.
  • SerdChunk authority β€” authority.
  • SerdChunk path_base β€” path prefix if relative.
  • SerdChunk path β€” path suffix.
  • SerdChunk query β€” query.
  • SerdChunk fragment β€” fragment.

✨ Typedef Documentation ✨

Okay bestie, these are the typedefs, aka the lil' nicknames for the structs so you don't have to type struct WhateverImpl every single time. You're welcome. πŸ’…

SerdEnv

typedef struct SerdEnvImpl SerdEnv

Environment. Represents the state required to resolve a CURIE or relative URI, e.g. the base URI and set of namespace prefixes at a particular point. It's giving "where am I and what do my prefixes mean right now". πŸ—ΊοΈ

SerdReader

typedef struct SerdReaderImpl SerdReader

RDF reader. Parses RDF by calling user-provided sink functions as input is consumed β€” much like an XML SAX parser. So it doesn't hand you a big tree, it just yells at your callbacks as it goes. πŸ“£

SerdWriter

typedef struct SerdWriterImpl SerdWriter

RDF writer. Provides a bunch of functions that let you write RDF syntax out to some stream. And the iconic part: these functions are deliberately compatible with the sink functions used by SerdReader, so you can literally plug a reader straight into a writer and re-serialise a document with minimal overhead. No cap, that's the whole flex. πŸ”₯

SerdStatementFlags

typedef uint32_t SerdStatementFlags

Bitwise OR of SerdStatementFlag values. Smoosh 'em together with |. πŸŽ€

SerdNodeFlags

typedef uint32_t SerdNodeFlags

Bitwise OR of SerdNodeFlag values. Same deal. πŸ¦‹

SerdStreamErrorFunc

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.

SerdSource

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

Source function for raw string input. Identical semantics to fread, but it may set errno for more informative error reporting than SerdStreamErrorFunc can give you. ✨

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.

SerdSink

typedef size_t(* SerdSink) (const void *buf, size_t len, void *stream)

Sink function for raw string output. That's it, that's the whole vibe. πŸ«—

SerdErrorSink

typedef SerdStatus(* SerdErrorSink) (void *handle, const SerdError *error)

Sink (callback) for errors. 🚨

Parameters

  • handle β€” Handle for user data.
  • error β€” Error description.

SerdBaseSink

typedef SerdStatus(* SerdBaseSink) (void *handle, const SerdNode *uri)

Sink (callback) for base URI changes. Called whenever the base URI of the serialisation changes. 🧭

SerdPrefixSink

typedef SerdStatus(* SerdPrefixSink) (void *handle, const SerdNode *name, const SerdNode *uri)

Sink (callback) for namespace definitions. Called whenever a prefix is defined in the serialisation. 🏷️

SerdStatementSink

typedef SerdStatus(* SerdStatementSink) (void *handle, SerdStatementFlags flags, const SerdNode *graph, const SerdNode *subject, const SerdNode *predicate, const SerdNode *object, const SerdNode *object_datatype, const SerdNode *object_lang)

Sink (callback) for statements. Called for every RDF statement in the serialisation. Every. Single. One. πŸ’–

SerdEndSink

typedef SerdStatus(* SerdEndSink) (void *handle, const SerdNode *node)

Sink (callback) for anonymous node end markers. This gets called to say that the anonymous node with the given value will no longer be referred to by any future statements β€” i.e. the anonymous serialisation of the node is finished. It's giving closure, literally. 🎬


🌈 Enumeration Type Documentation 🌈

enum SerdStatus

Return status code. Your classic "did it work tho" enum. πŸ‘‘

Enumerator

  • SERD_SUCCESS β€” No error. πŸŽ‰
  • SERD_FAILURE β€” Non-fatal failure. πŸ™ˆ
  • SERD_ERR_UNKNOWN β€” Unknown error. πŸ’€
  • SERD_ERR_BAD_SYNTAX β€” Invalid syntax.
  • SERD_ERR_BAD_ARG β€” Invalid argument.
  • SERD_ERR_NOT_FOUND β€” Not found.
  • SERD_ERR_ID_CLASH β€” Encountered clashing blank node IDs.
  • SERD_ERR_BAD_CURIE β€” Invalid CURIE (e.g. prefix does not exist)
  • SERD_ERR_INTERNAL β€” Unexpected internal error (should not happen)
bestie if you ever see SERD_ERR_INTERNAL... that's not on you. It literally says "should not happen". 😭

enum SerdSyntax

RDF syntax type. Pick your fighter. πŸ₯Š

Enumerator

  • SERD_TURTLE β€” Turtle - Terse RDF Triple Language (UTF-8).

See also

  • Turtle
  • SERD_NTRIPLES β€” NTriples - Line-based RDF triples (ASCII).

See also

  • NTriples
  • SERD_NQUADS β€” NQuads - Line-based RDF quads (UTF-8).

See also

  • NQuads
  • SERD_TRIG β€” TriG - Terse RDF quads (UTF-8).

See also

  • Trig

enum SerdStatementFlag

Flags indicating inline abbreviation information for a statement. This is the "how was this written down, aesthetically" enum. ✍️

Enumerator

  • SERD_EMPTY_S β€” Empty blank node subject.
  • SERD_EMPTY_O β€” Empty blank node object.
  • SERD_ANON_S_BEGIN β€” Start of anonymous subject.
  • SERD_ANON_O_BEGIN β€” Start of anonymous object.
  • SERD_ANON_CONT β€” Continuation of anonymous node.
  • SERD_LIST_S_BEGIN β€” Start of list subject.
  • SERD_LIST_O_BEGIN β€” Start of list object.
  • SERD_LIST_CONT β€” Continuation of list.

enum SerdType

Type of a syntactic RDF node. This is more precise than the type of an abstract RDF node. An abstract node is either a resource, literal, or blank. In syntax there are two ways to refer to a resource (by URI or CURIE) and two ways to refer to a blank (by ID or anonymously). Anonymous (inline) blank nodes are expressed using SerdStatementFlags rather than this type. Yeah, it's a lot β€” but you got this. πŸ’ͺ

Enumerator

  • SERD_NOTHING β€” The type of a nonexistent node. This type is useful as a sentinel, but is never emitted by the reader. (Ghost node energy. πŸ‘»)
  • SERD_LITERAL β€” Literal value. A literal optionally has either a language, or a datatype (not both). Not both, okay? Pick one. πŸ“
  • 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').

See also

  • SERD_CURIE β€” CURIE, a shortened URI. Value is an unquoted CURIE string relative to the current environment, e.g. 'rdf:type'.

See also

  • CURIE Syntax 1.0
  • SERD_BLANK β€” A blank node. Value is a blank node ID, e.g. 'id3', which is meaningful only within this serialisation. (Local legend only, doesn't travel. ✈️)

See also

  • Turtle nodeID

enum SerdNodeFlag

Flags indicating certain string properties relevant to serialisation. Basically "heads up, this string is spicy". 🌢️

Enumerator

  • SERD_HAS_NEWLINE β€” Contains line breaks ('\n' or '\r')
  • SERD_HAS_QUOTE β€” Contains quotes (''')

enum SerdStyle

Syntax style options. The style of the writer output can be controlled by ORing together values from this enumeration. Note that some options are only supported for some syntaxes (e.g. NTriples does not support abbreviation and is always ASCII). So yeah, check before you assume. πŸ‘€

Enumerator

  • SERD_STYLE_ABBREVIATED β€” Abbreviate triples when possible.
  • SERD_STYLE_ASCII β€” Escape all non-ASCII characters.
  • SERD_STYLE_RESOLVED β€” Resolve URIs against base URI.
  • SERD_STYLE_CURIED β€” Shorten URIs into CURIEs.
  • SERD_STYLE_BULK β€” Write output in pages.

πŸ’œ Function Documentation πŸ’œ

serd_free

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. So like, use this one for Serd stuff, mmkay? 🧹

serd_strerror

const uint8_t* serd_strerror (SerdStatus status)

Return a string describing a status code. Instant translation of your enum into words. πŸ—£οΈ

serd_strlen

size_t serd_strlen (const uint8_t * str, size_t * n_bytes, SerdNodeFlags * flags)

Measure a UTF-8 string. πŸ“

Returns

  • Length of str in characters (except NULL).

Parameters

  • str β€” A null-terminated UTF-8 string.
  • n_bytes β€” (Output) Set to the size of str in bytes (except NULL).
  • flags β€” (Output) Set to the applicable flags.

serd_strtod

double serd_strtod (const char * str, char ** endptr)

Parse a string to a double. The API of this function is identical to the standard C strtod function, except this function is locale-independent and always matches the lexical format used in the Turtle grammar (the decimal point is always '.'). So no, your locale can't sneak a comma in there. 🚫

serd_base64_decode

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

Decode a base64 string. This function can be used to deserialise a blob node created with serd_node_new_blob(). πŸ”“

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().
bestie, fr fr, free it with serd_free(). Don't make me say it twice. 🫢

serd_uri_to_path

const uint8_t* serd_uri_to_path (const uint8_t * uri)

Return the local path for uri, or NULL if uri is not a file URI. Note this (inappropriately named) function only removes the file scheme if necessary, and returns uri unmodified if it is an absolute path. Percent encoding and other issues are not handled, so to properly convert a file URI to a path, use serd_file_uri_parse(). Like... the name oversells it, honestly. πŸ™ˆ

serd_file_uri_parse

uint8_t* serd_file_uri_parse (const uint8_t * uri, uint8_t ** hostname)

Get the unescaped path and hostname from a file URI. The one that actually does the thing. ✨

Parameters

  • uri β€” A file URI.
  • hostname β€” If non-NULL, set to the hostname, if present.

Returns

  • The path component of the URI.

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

serd_uri_string_has_scheme

bool serd_uri_string_has_scheme (const uint8_t * utf8)

Return true iff utf8 starts with a valid URI scheme. Yes/no, no maybe. βœ…

serd_uri_parse

SerdStatus serd_uri_parse (const uint8_t * utf8, SerdURI * out)

Parse utf8, writing result to out. Short and sweet. 🍬

serd_uri_resolve

void serd_uri_resolve (const SerdURI * r, const SerdURI * base, SerdURI * t)

Set target t to reference r resolved against base. Classic "make it relative, make it absolute, whatever" move. 🧚

See also

serd_uri_serialise

size_t serd_uri_serialise (const SerdURI * uri, SerdSink sink, void * stream)

Serialise uri with a series of calls to sink. Drip-feed that URI out. πŸ’§

serd_uri_serialise_relative

size_t serd_uri_serialise_relative (const SerdURI * uri, const SerdURI * base, const SerdURI * root, SerdSink sink, void * stream)

Serialise uri relative to base with a series of calls to sink. The uri is written as a relative URI iff if it a child of base and root. The optional root parameter must be a prefix of base and can be used keep up-references ('../') within a certain namespace. So root is like the fence you're not allowed to hop. 🚧

serd_node_from_string

SerdNode serd_node_from_string (SerdType type, const uint8_t * str)

Make a (shallow) node from str. This measures, but does not copy, str. No memory is allocated. Shallow, like your ex's personality. πŸ’€ (jk jk, it's efficient and iconic.)

serd_node_from_substring

SerdNode serd_node_from_substring (SerdType type, const uint8_t * str, size_t len)

Make a (shallow) node from a prefix of str. This measures, but does not copy, str. No memory is allocated. Note that the returned node may not be null terminated. So don't go treating it like a C string and crying later. 😭

serd_node_copy

SerdNode serd_node_copy (const SerdNode * node)

Make a deep copy of node. The opposite of shallow. Growth. 🌱

Returns

  • a node that the caller must free with serd_node_free().

serd_node_equals

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

Return true iff a is equal to b. Are they the same? Find out now. 🫰

serd_node_new_uri_from_node

SerdNode serd_node_new_uri_from_node (const SerdNode * uri_node, const SerdURI * base, SerdURI * out)

Simple wrapper for serd_node_new_uri() to resolve a URI node. Convenience queen. πŸ‘‘

serd_node_new_uri_from_string

SerdNode serd_node_new_uri_from_string (const uint8_t * str, const SerdURI * base, SerdURI * out)

Simple wrapper for serd_node_new_uri() to resolve a URI string. Same energy, string flavoured. πŸ‹

serd_node_new_file_uri πŸ—‚οΈ

SerdNode serd_node_new_file_uri (const uint8_t * path, const uint8_t * hostname, SerdURI * out, bool escape)

okay so this one takes a file system path and an optional hostname and gives you back a brand new file URI node. Backslashes in Windows paths get converted, and '' will always be percent encoded. And if escape is true, then all the other invalid characters get percent encoded as well. slay.

If path is relative, hostname is just ignored entirely (not its moment, honestly πŸ’…). And if out isn't NULL, it gets set to the parsed URI. πŸŽ€


serd_node_new_uri ✨

SerdNode serd_node_new_uri (const SerdURI * uri, const SerdURI * base, SerdURI * out)

Creates a new node by serialising uri into a whole new string. iconic behaviour.

Parameters

  • uri β€” the URI to serialise.
  • base β€” base URI to resolve uri against (or NULL if you want no resolution at all).
  • out β€” set to the parsing of the new URI (i.e. it points only to memory owned by the new returned node). πŸ‘‘

serd_node_new_relative_uri πŸ¦‹

SerdNode serd_node_new_relative_uri (const SerdURI * uri, const SerdURI * base, const SerdURI * root, SerdURI * out)

Creates a new node by serialising uri into a new relative URI. yes bestie, we're being modest about it.

Parameters

  • uri β€” the URI to serialise.
  • base β€” base URI to make uri relative to, if possible.
  • root β€” root URI for resolution (see serd_uri_serialise_relative()).
  • out β€” set to the parsing of the new URI (i.e. it points only to memory owned by the new returned node).

serd_node_new_decimal πŸ“

SerdNode serd_node_new_decimal (double d, unsigned frac_digits)

Makes a new node by serialising d into an xsd:decimal string. And the rules here are strict, bestie β€” listen up:

  • the resulting node will always contain a .
  • it will start with a digit
  • it will end with a digit

So yeah, it'll have a leading and/or trailing 0 if it needs one. It will never be in scientific notation. A maximum of frac_digits digits get written after the decimal point, but trailing zeros get automatically omitted β€” except for one, if d is a round integer.

ngl, this next bit is a whole fact: about 16 fractional digits are needed to precisely represent a double, and about 8 for a float. 😭

Parameters

  • d β€” the value for the new node.
  • frac_digits β€” the maximum number of digits after the decimal place.

serd_node_new_integer πŸ”’

SerdNode serd_node_new_integer (int64_t i)

Makes a new node by serialising i into an xsd:integer string. short, sweet, ate.


serd_node_new_blob 🫢

SerdNode serd_node_new_blob (const void * buf, size_t size, bool wrap_lines)

Creates a node by serialising buf into an xsd:base64Binary string. This is the move when you need to make a serialisable node out of arbitrary binary data β€” and you can decode it back with serd_base64_decode(). πŸ’–

Parameters

  • buf β€” raw binary input data.
  • size β€” size of buf.
  • wrap_lines β€” wrap lines at 76 characters to conform to RFC 2045.

serd_node_free 🧹

void serd_node_free (SerdNode * node)

Frees any data owned by node. ⚠️ But lowkey read this twice: if node is itself dynamically allocated β€” which is not the case for nodes created internally by serd β€” then it will not be freed. So don't come crying to me later, bestie. 😭


serd_env_new 🌸

SerdEnv* serd_env_new (const SerdNode * base_uri)

Creates a new environment. fresh start energy.


serd_env_free πŸ’€

void serd_env_free (SerdEnv * env)

Frees it. the docs say, and I quote, "Free ns." and honestly? we respect the chaos. free the thing. πŸŽ€


serd_env_get_base_uri ⭐

const SerdNode* serd_env_get_base_uri (const SerdEnv * env, SerdURI * out)

Gets the current base URI. that's the whole vibe.


serd_env_set_base_uri ✨

SerdStatus serd_env_set_base_uri (SerdEnv * env, const SerdNode * uri)

Sets the current base URI. periodt.


serd_env_set_prefix πŸŽ€

SerdStatus serd_env_set_prefix (SerdEnv * env, const SerdNode * name, const SerdNode * uri)

Sets a namespace prefix. cute, necessary, done.


serd_env_set_prefix_from_strings 🌈

SerdStatus serd_env_set_prefix_from_strings (SerdEnv * env, const uint8_t * name, const uint8_t * uri)

Also sets a namespace prefix β€” but this time you're feeding it strings directly. same energy, different entry point. πŸ’…


serd_env_qualify 🧚

bool serd_env_qualify (const SerdEnv * env, const SerdNode * uri, SerdNode * prefix, SerdChunk * suffix)

Qualifies uri into a CURIE if it possibly can. and if it can't? it just tells you the truth. πŸ’œ


serd_env_expand πŸ”₯

SerdStatus serd_env_expand (const SerdEnv * env, const SerdNode * curie, SerdChunk * uri_prefix, SerdChunk * uri_suffix)

Expands curie. Errors: SERD_ERR_BAD_ARG if curie is not valid, or SERD_ERR_BAD_CURIE if the prefix is not defined in env. so yeah, two ways to fail, both clearly labelled, we love a well-documented L. πŸ™ˆ


serd_env_expand_node πŸ¦‹

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

Expands node β€” which must be a CURIE or a URI β€” into a full URI. Returns null if node can not be expanded. πŸ’–


serd_env_foreach πŸ‘‘

void serd_env_foreach (const SerdEnv * env, SerdPrefixSink func, void * handle)

Calls func for each prefix defined in env. one by one, no skips, main character energy.


serd_reader_new πŸ“–

SerdReader* serd_reader_new (SerdSyntax syntax, void * handle, void(*)(void *) free_handle, SerdBaseSink base_sink, SerdPrefixSink prefix_sink, SerdStatementSink statement_sink, SerdEndSink end_sink)

Creates a new RDF reader. the whole cast is here β€” syntax, handle, free_handle, base_sink, prefix_sink, statement_sink, end_sink β€” and they all showed up on time. πŸ”₯


serd_reader_set_strict 😀

void serd_reader_set_strict (SerdReader * reader, bool strict)

Enables or disables strict parsing. by default the reader is non-strict (lax), which means it'll tolerate URIs with invalid characters. Setting strict will make it fail when it's parsing files like that. Either way β€” strict or lax β€” an error gets printed for invalid input. so you will know. πŸ’€


serd_reader_set_error_sink 🚨

void serd_reader_set_error_sink (SerdReader * reader, SerdErrorSink error_sink, void * error_handle)

Sets a function to be called whenever errors happen while reading. The error_sink gets called with handle as its first argument. And if no error function is set? errors get printed to stderr in GCC style. old school but it works. ✨


serd_reader_get_handle 🫴

void* serd_reader_get_handle (const SerdReader * reader)

Returns the handle that was passed to serd_reader_new(). right back where it came from. πŸŽ€


serd_reader_add_blank_prefix 🏷️

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

Sets a prefix to be added to all blank node identifiers. And ngl this one is genuinely important, so listen up: this is useful when multiple files are going to be parsed into the same output β€” like a store, or other files. Since Serd preserves blank node IDs, this could cause conflicts where two non-equivalent blank nodes get merged, which results in corrupt data. 😭

so by setting a unique blank node prefix for each parsed file, you avoid all of that β€” while still preserving the blank node names. obsessed with a fix that doesn't break anything else. πŸ’–

serd_reader_set_default_graph πŸ•ΈοΈ

void serd_reader_set_default_graph (SerdReader * reader, const SerdNode * graph)

Sets the URI of the default graph. If you set this, the reader will emit quads with the graph set to the given node for any statements that are not in a named graph β€” which is currently all of them, since Serd currently does not support any graph syntaxes. 😌 so like, it's giving "default", and it means it.


serd_reader_read_file πŸ“‚

SerdStatus serd_reader_read_file (SerdReader * reader, const uint8_t * uri)

Reads a file at a given uri. straightforward, no notes. ⭐


serd_reader_start_stream 🌊

SerdStatus serd_reader_start_stream (SerdReader * reader, FILE * file, const uint8_t * name, bool bulk)

Starts an incremental read from a file handle. Iff bulk is true, file gets read a page at a time β€” which is more efficient, but it uses a page of memory and it means an entire page of input must be ready before any callbacks will fire. 🫠

so if you want to react as soon as input arrives, set bulk to false. bestie's choice.

serd_reader_start_source_stream πŸ’«

SerdStatus serd_reader_start_source_stream (SerdReader * reader, SerdSource read_func, SerdStreamErrorFunc error_func, void * stream, const uint8_t * name, size_t page_size)

Starts an incremental read from a user-specified source. And here's the guarantee, no cap: read_func is only ever called for page_size elements with size 1 (i.e. page_size bytes). πŸ“


serd_reader_read_chunk 🍫

SerdStatus serd_reader_read_chunk (SerdReader * reader)

Reads a single 'chunk' of data during an incremental read. This function reads a single top level description and then returns. That might be a directive, a statement, or several statements β€” essentially it reads until a . is encountered. which makes it especially useful for reading directly from a pipe or socket. πŸŽ€


serd_reader_end_stream πŸ›‘

SerdStatus serd_reader_end_stream (SerdReader * reader)

Finishes an incremental read from a file handle. wrap it up, we're done here. πŸ’…


serd_reader_read_file_handle πŸ—ƒοΈ

SerdStatus serd_reader_read_file_handle (SerdReader * reader, FILE * file, const uint8_t * name)

Reads file. yes that's the whole description. sometimes the icon is brief. πŸ‘‘


serd_reader_read_source πŸ”Œ

SerdStatus serd_reader_read_source (SerdReader * reader, SerdSource source, SerdStreamErrorFunc error, void * stream, const uint8_t * name, size_t page_size)

Reads a user-specified byte source. πŸ¦‹


serd_reader_read_string 🧡

SerdStatus serd_reader_read_string (SerdReader * reader, const uint8_t * utf8)

Reads utf8. short king behaviour. ✨


serd_reader_free 🧼

void serd_reader_free (SerdReader * reader)

Frees reader. bye bestie, thank you for your service. πŸ’–


serd_writer_new ✍️

SerdWriter* serd_writer_new (SerdSyntax syntax, SerdStyle style, SerdEnv * env, const SerdURI * base_uri, SerdSink ssink, void * stream)

Creates a new RDF writer. syntax, style, env, base_uri, ssink, stream β€” the full lineup, and it's giving main character. 🌟


serd_writer_free 🫧

void serd_writer_free (SerdWriter * writer)

Frees writer. clean exit, no drama.


serd_writer_get_env 🌍

SerdEnv* serd_writer_get_env (SerdWriter * writer)

Returns the env that the writer is using. it's right there. πŸŽ€


serd_file_sink πŸ“

size_t serd_file_sink (const void * buf, size_t len, void * stream)

A convenience sink function for writing to a FILE*. You can use this as a SerdSink when you're writing to a FILE*. And the stream parameter must be a FILE* opened for writing. ⚠️ don't be cute about it.


serd_chunk_sink 🍰

size_t serd_chunk_sink (const void * buf, size_t len, void * stream)

A convenience sink function for writing to a string. Use this as a SerdSink to write into a SerdChunk, which gets resized as necessary with realloc(). The stream parameter must point to an initialized SerdChunk. And when the write is finished, you retrieve the string with serd_chunk_sink_finish(). πŸ’–


serd_chunk_sink_finish 🎁

uint8_t* serd_chunk_sink_finish (SerdChunk * stream)

Finishes a serialisation to a chunk with serd_chunk_sink(). The returned string is the result of the serialisation, it's NULL terminated (by this function), and it's owned by the caller. so it's yours now. take care of it. 🫢


serd_writer_set_error_sink 🚨

void serd_writer_set_error_sink (SerdWriter * writer, SerdErrorSink error_sink, void * error_handle)

Sets a function to be called whenever errors happen while writing. The error_sink gets called with handle as its first argument. And if no error function is set, errors get printed to stderr. 😭


serd_writer_chop_blank_prefix βœ‚οΈ

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

Sets a prefix to be removed from matching blank node identifiers. chop chop. πŸ’…


serd_writer_set_base_uri 🧭

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

Sets the current output base URI (and emits a directive if applicable). πŸ“Œ also note, and this is a nice little fact: this function can be safely casted to SerdBaseSink.


serd_writer_set_root_uri 🌳

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

Sets the current root URI. okay so this one has lore, pay attention:

  • 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

And if the root is not explicitly set, it defaults to the base URI β€” which means no up-references will be created at all. 🫠


serd_writer_set_prefix 🏷️

SerdStatus serd_writer_set_prefix (SerdWriter * writer, const SerdNode * name, const SerdNode * uri)

Sets a namespace prefix (and emits a directive if applicable). πŸ’« also, this function can be safely casted to SerdPrefixSink.


serd_writer_write_statement ✍️

SerdStatus serd_writer_write_statement (SerdWriter * writer, SerdStatementFlags flags, const SerdNode * graph, const SerdNode * subject, const SerdNode * predicate, const SerdNode * object, const SerdNode * datatype, const SerdNode * lang)

Writes a statement. that's it, that's the job. πŸŽ€ and yes β€” this function can be safely casted to SerdStatementSink.


serd_writer_end_anon πŸ‘»

SerdStatus serd_writer_end_anon (SerdWriter * writer, const SerdNode * node)

Marks the end of an anonymous node's description. so long, anon. 🌫️ and this function can be safely casted to SerdEndSink.


serd_writer_finish 🏁

SerdStatus serd_writer_finish (SerdWriter * writer)

Finishes a write. that's a wrap, bestie. πŸ’–

🌈 VARIABLE DOCUMENTATION πŸ’…

okay so these are the two lil' global constants that Serd just... has. sitting there. being iconic. ✨

πŸ’– const SerdURI SERD_URI_NULL [static]

bestie this one is literally the empty URI. the void. the "no thoughts, head empty" URI. 🫢

its initial value is, verbatim:

= {
    {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}
}

six chunks, all of them {NULL, 0}, aka nothing and zero. that's it. that's the girl. πŸ’€

πŸ’œ const SerdNode SERD_NODE_NULL = { NULL, 0, 0, 0, SERD_NOTHING } [static]

and here's her sibling β€” the null node, no cap. πŸŽ€ it's declared static and its value is exactly:

{ NULL, 0, 0, 0, SERD_NOTHING }

which is giving "a node that has no data, no length, no flags, and the type SERD_NOTHING". she is nothing and she's at peace with it. we love a low-maintenance queen. πŸ‘‘


🌸 AUTHOR 🌸

  • Generated by Doxygen for Serd from the source code β€” and then modified by Dennis Braun <d_braun@kabelmail.de>. πŸ’–

okay bestie that's the whole page, we ate and left no crumbs πŸ”₯ this was Serd's manual, from source/version Serd dated '2020-04-28', page SERD(3) β€” go forth and parse some RDF, main character. mwah. πŸ’…βœ¨πŸ¦‹