aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-07-22 23:39:39 -0400
committerDavid Robillard <d@drobilla.net>2022-01-14 19:37:51 -0500
commita63a8f19c54dfee75e092819d6622b8d36fe1d39 (patch)
tree3c2fe49c257e27d369365a0c08c1524baaf74a4c /include
parent64e81dfd6ec04995fd396269deb6b32fe2d1192d (diff)
downloadserd-a63a8f19c54dfee75e092819d6622b8d36fe1d39.tar.gz
serd-a63a8f19c54dfee75e092819d6622b8d36fe1d39.tar.bz2
serd-a63a8f19c54dfee75e092819d6622b8d36fe1d39.zip
Expose low-level node construction API
Diffstat (limited to 'include')
-rw-r--r--include/serd/serd.h387
1 files changed, 322 insertions, 65 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h
index 2bda9829..fe610fc5 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -600,81 +600,337 @@ typedef enum {
} SerdNodeType;
/**
- Create a new "token" node that is just a string.
+ @defgroup serd_node_construction Construction
+
+ This is the low-level node construction API, which can be used to construct
+ nodes into existing buffers. Advanced applications can use this to
+ specially manage node memory, for example by allocating nodes on the stack,
+ or with a special allocator.
+
+ Note that nodes are "plain old data", so there is no need to destroy a
+ constructed node, and nodes may be trivially copied, for example with
+ memcpy().
+
+ @{
+*/
+
+/**
+ Construct a node into an existing buffer.
+
+ This is the universal node constructor which can construct any node. An
+ error will be returned if the parameters do not make sense. In particular,
+ SERD_HAS_DATATYPE or SERD_HAS_LANGUAGE (but not both) may only be given if
+ `type` is `SERD_LITERAL`, and `meta` must be syntactically valid based on
+ that flag.
+
+ This function may also be used to determine the size of buffer required by
+ passing a null buffer with zero size.
+
+ @param buf_size The size of `buf` in bytes, or zero to only measure.
+
+ @param buf Buffer where the node will be written, or null to only measure.
+
+ @param type The type of the node to construct.
+
+ @param string The string body of the node.
+
+ @param flags Flags that describe the details of the node.
+
+ @param meta The string value of the literal's metadata. If
+ #SERD_HAS_DATATYPE is set, then this must be an absolute datatype URI. If
+ #SERD_HAS_LANGUAGE is set, then this must be a language tag like "en-ca".
+ Otherwise, it is ignored.
+
+ @return A result with a `status` and a `count` of bytes written. If the
+ buffer is too small for the node, then `status` will be #SERD_ERR_OVERFLOW,
+ and `count` will be set to the number of bytes required to successfully
+ construct the node.
+*/
+SERD_API
+SerdWriteResult
+serd_node_construct(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ SerdNodeType type,
+ SerdStringView string,
+ SerdNodeFlags flags,
+ SerdStringView meta);
+
+/**
+ Construct a simple "token" node.
"Token" is just a shorthand used in this API to refer to a node that is not
- a typed or tagged literal. This can be used to create URIs, blank nodes,
- variables, and simple string literals.
+ a typed or tagged literal, that is, a node that is just one string. This
+ can be used to create URIs, blank nodes, variables, and simple string
+ literals.
Note that string literals constructed with this function will have no flags
set, and so will be written as "short" literals (not triple-quoted). To
- construct long literals, use the more advanced serd_new_literal() with
- #SERD_IS_LONG.
+ construct long literals, use the more advanced serd_construct_literal() with
+ the #SERD_IS_LONG flag.
+
+ See the serd_node_construct() documentation for details on buffer usage and
+ the return value.
*/
SERD_API
-SerdNode* SERD_ALLOCATED
-serd_new_token(SerdNodeType type, SerdStringView string);
+SerdWriteResult
+serd_node_construct_token(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ SerdNodeType type,
+ SerdStringView string);
+
+/**
+ Construct a URI node from a parsed URI.
+
+ This is similar to serd_node_construct_token(), but will serialise a parsed
+ URI into the new node. This can be used to resolve a relative URI reference
+ or expand a CURIE directly into a node without needing to allocate the URI
+ string separately.
+*/
+SerdWriteResult
+serd_node_construct_uri(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ SerdURIView uri);
+
+/**
+ Construct a file URI node from a path and optional hostname.
-/// Create a new plain literal string node from `str`
+ This is similar to serd_node_construct_token(), but will create a new file
+ URI from a file path and optional hostname, performing any necessary
+ escaping.
+*/
+SerdWriteResult
+serd_node_construct_file_uri(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ SerdStringView path,
+ SerdStringView hostname);
+
+/**
+ Construct a literal node with an optional datatype or language.
+
+ Either a datatype (which must be an absolute URI) or a language (which must
+ be an RFC5646 language tag) may be given, but not both.
+
+ This is the most general literal constructor, which can be used to construct
+ any literal node. This works like serd_node_construct(), see its
+ documentation for details.
+*/
SERD_API
-SerdNode* SERD_ALLOCATED
-serd_new_string(SerdStringView string);
+SerdWriteResult
+serd_node_construct_literal(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ SerdStringView string,
+ SerdNodeFlags flags,
+ SerdStringView meta);
/**
- Create a new literal node with optional datatype or language.
+ Construct a canonical xsd:boolean literal.
- This can create more complex literals than serd_new_string() with an
- associated datatype URI or language tag, as well as control whether a
- literal should be written as a short or long (triple-quoted) string.
+ The constructed node will be either "true" or "false", with datatype
+ xsd:boolean.
- @param string The string value of the literal.
+ This is a convenience wrapper for serd_node_construct_literal() that
+ constructs a node directly from a `bool`.
+*/
+SerdWriteResult
+serd_node_construct_boolean(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ bool value);
- @param flags Flags to describe the literal and its metadata. This must be a
- valid combination of flags, in particular, at most one of #SERD_HAS_DATATYPE
- and #SERD_HAS_LANGUAGE may be set.
+/**
+ Construct a canonical xsd:decimal literal.
- @param meta The string value of the literal's metadata. If
- #SERD_HAS_DATATYPE is set, then this must be an absolute datatype URI. If
- #SERD_HAS_LANGUAGE is set, then this must be a language tag like "en-ca".
- Otherwise, it is ignored.
+ The constructed node will be an xsd:decimal literal, like "12.34", with
+ datatype xsd:decimal.
- @return A newly allocated literal node that must be freed with
- serd_node_free(), or null if the arguments are invalid or allocation failed.
+ The 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.
+
+ This is a convenience wrapper for serd_node_construct_literal() that
+ constructs a node directly from a `double`.
+*/
+SerdWriteResult
+serd_node_construct_decimal(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ double value);
+
+/**
+ Construct a canonical xsd:double literal.
+
+ The constructed node will be an xsd:double literal, like "1.23E45", with
+ datatype xsd:double. A canonical xsd:double is always in scientific
+ notation.
+
+ This is a convenience wrapper for serd_node_construct_literal() that
+ constructs a node directly from a `double`.
+*/
+SerdWriteResult
+serd_node_construct_double(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ double value);
+
+/**
+ Construct a canonical xsd:float literal.
+
+ The constructed node will be an xsd:float literal, like "1.23E45", with
+ datatype xsd:float. A canonical xsd:float is always in scientific notation.
+
+ Uses identical formatting to serd_node_construct_double(), except with at
+ most 9 significant digits (under 14 characters total).
+
+ This is a convenience wrapper for serd_node_construct_literal() that
+ constructs a node directly from a `float`.
+*/
+SerdWriteResult
+serd_node_construct_float(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ float value);
+
+/**
+ Construct a canonical xsd:integer literal.
+
+ The constructed node will be an xsd:integer literal like "1234", with the
+ given datatype, or datatype xsd:integer if none is given. It is the
+ caller's responsibility to ensure that the value is within the range of the
+ given datatype.
+*/
+SerdWriteResult
+serd_node_construct_integer(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ int64_t value,
+ SerdStringView datatype);
+
+/**
+ Construct a canonical xsd:base64Binary literal.
+
+ The constructed node will be an xsd:base64Binary literal like "Zm9vYmFy",
+ with datatype xsd:base64Binary.
+*/
+SerdWriteResult
+serd_node_construct_base64(size_t buf_size,
+ void* SERD_NULLABLE buf,
+ size_t value_size,
+ const void* SERD_NONNULL value,
+ SerdStringView datatype);
+
+/**
+ @}
+ @defgroup serd_node_allocation Dynamic Allocation
+
+ This is a convenient higher-level node construction API which allocates
+ nodes on the heap. The returned nodes must be freed with serd_node_free().
+
+ Note that in most cases it is better to use a #SerdNodes instead of managing
+ individual node allocations.
+
+ @{
+*/
+
+/**
+ Create a new node of any type.
+
+ This is a wrapper for serd_node_construct() that allocates a new node on the
+ heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
-serd_new_literal(SerdStringView string,
- SerdNodeFlags flags,
- SerdStringView meta);
+serd_node_new(SerdNodeType type,
+ SerdStringView string,
+ SerdNodeFlags flags,
+ SerdStringView meta);
+
+/**
+ Create a new simple "token" node.
+
+ This is a wrapper for serd_node_construct_token() that allocates a new node
+ on the heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
+*/
+SERD_API
+SerdNode* SERD_ALLOCATED
+serd_new_token(SerdNodeType type, SerdStringView string);
+
+/**
+ Create a new string literal node.
+
+ This is a trivial wrapper for serd_new_token() that passes `SERD_LITERAL`
+ for the type.
-/// Create a new blank node
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
+*/
SERD_API
SerdNode* SERD_ALLOCATED
-serd_new_blank(SerdStringView string);
+serd_new_string(SerdStringView string);
-/// Create a new URI node
+/**
+ Create a new URI node from a string.
+
+ This is a wrapper for serd_node_construct_uri() that allocates a new
+ node on the heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
+*/
SERD_API
SerdNode* SERD_ALLOCATED
serd_new_uri(SerdStringView string);
-/// Create a new URI from a URI view
+/**
+ Create a new URI node from a parsed URI.
+
+ This is a wrapper for serd_node_construct_uri() that allocates a new
+ node on the heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
+*/
SERD_API
SerdNode* SERD_ALLOCATED
serd_new_parsed_uri(SerdURIView uri);
/**
- Create a new file URI node from a file system path and optional hostname.
+ Create a new file URI node from a path and optional hostname.
- Backslashes in Windows paths will be converted, and other characters will be
- percent encoded as necessary.
+ This is a wrapper for serd_node_construct_file_uri() that allocates a new
+ node on the heap.
- If `path` is relative, `hostname` is ignored.
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
serd_new_file_uri(SerdStringView path, SerdStringView hostname);
-/// Create a new node by serialising `b` into an xsd:boolean string
+/**
+ Create a new literal node.
+
+ This is a wrapper for serd_node_construct_literal() that allocates a new
+ node on the heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
+*/
+SERD_API
+SerdNode* SERD_ALLOCATED
+serd_new_literal(SerdStringView string,
+ SerdNodeFlags flags,
+ SerdStringView meta);
+
+/**
+ Create a new canonical xsd:boolean node.
+
+ This is a wrapper for serd_node_construct_boolean() that allocates a new
+ node on the heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
+*/
SERD_API
SerdNode* SERD_ALLOCATED
serd_new_boolean(bool b);
@@ -682,29 +938,24 @@ serd_new_boolean(bool b);
/**
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.
+ This is a wrapper for serd_node_construct_decimal() that allocates a new
+ node on the heap.
- @param d The value for the new node.
- @param datatype Datatype of node, or NULL for xsd:decimal.
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
-serd_new_decimal(double d, const SerdNode* SERD_NULLABLE datatype);
+serd_new_decimal(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.
+ This is a wrapper for serd_node_construct_double() that allocates a new
+ node on the heap.
- Uses the shortest possible representation that precisely describes `d`,
- which has at most 17 significant digits (under 24 characters total).
-
- @param d Double value to write.
- @return A literal node with datatype xsd:double.
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
@@ -713,11 +964,11 @@ serd_new_double(double d);
/**
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).
+ This is a wrapper for serd_node_construct_float() that allocates a new
+ node on the heap.
- @param f Float value of literal.
- @return A literal node with datatype xsd:float.
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
@@ -726,28 +977,34 @@ serd_new_float(float f);
/**
Create a new canonical xsd:integer literal.
- @param i Integer value of literal.
- @param datatype Datatype of node, or NULL for xsd:integer.
+ This is a wrapper for serd_node_construct_integer() that allocates a new
+ node on the heap.
+
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
-serd_new_integer(int64_t i, const SerdNode* SERD_NULLABLE datatype);
+serd_new_integer(int64_t i, SerdStringView 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().
+ This is a wrapper for serd_node_construct_base64() that allocates a new
+ node on the heap.
- @param buf Raw binary data to encode in node.
- @param size Size of `buf` in bytes.
- @param datatype Datatype of node, or null for xsd:base64Binary.
+ @return A newly allocated node that must be freed with serd_node_free(), or
+ null.
*/
SERD_API
SerdNode* SERD_ALLOCATED
-serd_new_base64(const void* SERD_NONNULL buf,
- size_t size,
- const SerdNode* SERD_NULLABLE datatype);
+serd_new_base64(const void* SERD_NONNULL buf,
+ size_t size,
+ SerdStringView datatype);
+
+/**
+ @}
+*/
/**
Return the value of `node` as a boolean.