aboutsummaryrefslogtreecommitdiffstats
path: root/include/serd/node.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/serd/node.h')
-rw-r--r--include/serd/node.h243
1 files changed, 243 insertions, 0 deletions
diff --git a/include/serd/node.h b/include/serd/node.h
new file mode 100644
index 00000000..8f85a8d7
--- /dev/null
+++ b/include/serd/node.h
@@ -0,0 +1,243 @@
+// Copyright 2011-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef SERD_NODE_H
+#define SERD_NODE_H
+
+#include "serd/attributes.h"
+#include "serd/uri.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+SERD_BEGIN_DECLS
+
+/**
+ @defgroup serd_node Node
+ @ingroup serd_data
+ @{
+*/
+
+/**
+ 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).
+
+ 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.
+*/
+typedef enum {
+ /**
+ The type of a nonexistent node.
+
+ This type is useful as a sentinel, but is never emitted by the reader.
+ */
+ SERD_NOTHING = 0,
+
+ /**
+ Literal value.
+
+ A literal is a string that optionally has either a language, or a datatype
+ (but never both). Literals can only occur as the object of a statement,
+ never the subject or predicate.
+ */
+ SERD_LITERAL = 1,
+
+ /**
+ Universal Resource Identifier (URI).
+
+ A URI (more pedantically, a URI reference) is either a relative reference
+ with respect to some base URI, like "foo/bar", or an absolute URI with a
+ scheme, like "http://example.org/foo".
+
+ @see [RFC3986](http://tools.ietf.org/html/rfc3986)
+ */
+ SERD_URI = 2,
+
+ /**
+ CURIE, a shortened URI.
+
+ Value is an unquoted CURIE string relative to the current environment,
+ e.g. "rdf:type". @see [CURIE Syntax 1.0](http://www.w3.org/TR/curie)
+ */
+ SERD_CURIE = 3,
+
+ /**
+ A blank node.
+
+ A blank node is a resource that has no URI. The identifier of a blank
+ node is local to its context (a document, for example), and so unlike
+ URIs, blank nodes can't be used to link data across sources.
+
+ @see [RDF 1.1
+ Turtle](http://www.w3.org/TR/turtle/#grammar-production-BLANK_NODE_LABEL)
+ */
+ SERD_BLANK = 4,
+} SerdNodeType;
+
+/// Node flags, which ORed together make a #SerdNodeFlags
+typedef enum {
+ SERD_HAS_NEWLINE = 1U << 0U, ///< Contains line breaks ('\\n' or '\\r')
+ SERD_HAS_QUOTE = 1U << 1U, ///< Contains quotes ('"')
+} SerdNodeFlag;
+
+/// Bitwise OR of #SerdNodeFlag values
+typedef uint32_t SerdNodeFlags;
+
+/// A syntactic RDF node
+typedef struct {
+ const char* SERD_NULLABLE buf; ///< Value string
+ size_t n_bytes; ///< Size in bytes (excluding null)
+ SerdNodeFlags flags; ///< Node flags (string properties)
+ SerdNodeType type; ///< Node type
+} SerdNode;
+
+static const SerdNode SERD_NODE_NULL = {NULL, 0, 0, SERD_NOTHING};
+
+/**
+ Make a (shallow) node from `str`.
+
+ This measures, but does not copy, `str`. No memory is allocated.
+*/
+SERD_API SerdNode
+serd_node_from_string(SerdNodeType type, const char* SERD_NULLABLE str);
+
+/**
+ 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.
+*/
+SERD_API SerdNode
+serd_node_from_substring(SerdNodeType type,
+ const char* SERD_NULLABLE str,
+ size_t len);
+
+/// Simple wrapper for serd_node_new_uri() to resolve a URI node
+SERD_API SerdNode
+serd_node_new_uri_from_node(const SerdNode* SERD_NONNULL uri_node,
+ const SerdURIView* SERD_NULLABLE base,
+ SerdURIView* SERD_NULLABLE out);
+
+/// Simple wrapper for serd_node_new_uri() to resolve a URI string
+SERD_API SerdNode
+serd_node_new_uri_from_string(const char* SERD_NULLABLE str,
+ const SerdURIView* SERD_NULLABLE base,
+ SerdURIView* SERD_NULLABLE out);
+
+/**
+ 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.
+ If `out` is not NULL, it will be set to the parsed URI.
+*/
+SERD_API SerdNode
+serd_node_new_file_uri(const char* SERD_NONNULL path,
+ const char* SERD_NULLABLE hostname,
+ SerdURIView* SERD_NULLABLE out);
+
+/**
+ Create a new node by serialising `uri` into a new string.
+
+ @param uri The URI to serialise.
+
+ @param base Base URI to resolve `uri` against (or NULL for no resolution).
+
+ @param out Set to the parsing of the new URI (i.e. points only to
+ memory owned by the new returned node).
+*/
+SERD_API SerdNode
+serd_node_new_uri(const SerdURIView* SERD_NONNULL uri,
+ const SerdURIView* SERD_NULLABLE base,
+ SerdURIView* SERD_NULLABLE out);
+
+/**
+ Create a new node by serialising `uri` into a new relative URI.
+
+ @param uri The URI to serialise.
+
+ @param base Base URI to make `uri` relative to, if possible.
+
+ @param root Root URI for resolution (see serd_uri_serialise_relative()).
+
+ @param out Set to the parsing of the new URI (i.e. points only to
+ memory owned by the new returned node).
+*/
+SERD_API SerdNode
+serd_node_new_relative_uri(const SerdURIView* SERD_NONNULL uri,
+ const SerdURIView* SERD_NULLABLE base,
+ const SerdURIView* SERD_NULLABLE root,
+ SerdURIView* SERD_NULLABLE out);
+
+/**
+ Create a new node by serialising `d` into an xsd:decimal string.
+
+ The resulting node will always contain a '.', start with a digit, and end
+ with a digit (i.e. will have a leading and/or trailing '0' if necessary).
+ It will never be in scientific notation. A maximum of `frac_digits` digits
+ will be written after the decimal point, but trailing zeros will
+ automatically be omitted (except one if `d` is a round integer).
+
+ Note that about 16 and 8 fractional digits are required to precisely
+ represent a double and float, respectively.
+
+ @param d The value for the new node.
+ @param frac_digits The maximum number of digits after the decimal place.
+*/
+SERD_API SerdNode
+serd_node_new_decimal(double d, unsigned frac_digits);
+
+/// Create a new node by serialising `i` into an xsd:integer string
+SERD_API SerdNode
+serd_node_new_integer(int64_t i);
+
+/**
+ Create a node by serialising `buf` into an xsd:base64Binary string.
+
+ This function can be used to make a serialisable node out of arbitrary
+ binary data, which can be decoded using serd_base64_decode().
+
+ @param buf Raw binary input data.
+ @param size Size of `buf`.
+ @param wrap_lines Wrap lines at 76 characters to conform to RFC 2045.
+*/
+SERD_API SerdNode
+serd_node_new_blob(const void* SERD_NONNULL buf, size_t size, bool wrap_lines);
+
+/**
+ Make a deep copy of `node`.
+
+ @return a node that the caller must free with serd_node_free().
+*/
+SERD_API SerdNode
+serd_node_copy(const SerdNode* SERD_NULLABLE node);
+
+/// Return true iff `a` is equal to `b`
+SERD_PURE_API
+bool
+serd_node_equals(const SerdNode* SERD_NONNULL a,
+ const SerdNode* SERD_NONNULL b);
+
+/**
+ Free any data owned by `node`.
+
+ Note that if `node` is itself dynamically allocated (which is not the case
+ for nodes created internally by serd), it will not be freed.
+*/
+SERD_API void
+serd_node_free(SerdNode* SERD_NULLABLE node);
+
+/**
+ @}
+*/
+
+SERD_END_DECLS
+
+#endif // SERD_NODE_H