aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-12-20 13:02:24 -0500
committerDavid Robillard <d@drobilla.net>2018-12-31 11:37:49 -0500
commit88d62648449a3f7d8e31a70d3d81dec6c895dd31 (patch)
treec63472ef33552484b8590ed168424685e4b306d2
parent66412dc1084040263f8ec75fde51129176a053de (diff)
downloadserd-88d62648449a3f7d8e31a70d3d81dec6c895dd31.tar.gz
serd-88d62648449a3f7d8e31a70d3d81dec6c895dd31.tar.bz2
serd-88d62648449a3f7d8e31a70d3d81dec6c895dd31.zip
Add serd_node_compare()
-rw-r--r--serd/serd.h11
-rw-r--r--src/node.c28
2 files changed, 39 insertions, 0 deletions
diff --git a/serd/serd.h b/serd/serd.h
index ce968a28..06bff454 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -643,6 +643,17 @@ bool
serd_node_equals(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.
+*/
+SERD_API
+int
+serd_node_compare(const SerdNode* a, const SerdNode* b);
+
+/**
Create a new URI from a string.
*/
SERD_API
diff --git a/src/node.c b/src/node.c
index 859cb0a3..b0e8f991 100644
--- a/src/node.c
+++ b/src/node.c
@@ -66,6 +66,14 @@ serd_node_pad_size(const size_t n_bytes)
}
static const SerdNode*
+serd_node_maybe_get_meta_c(const SerdNode* node)
+{
+ return (node->flags & (SERD_HAS_LANGUAGE | SERD_HAS_DATATYPE))
+ ? (node + 1 + (serd_node_pad_size(node->n_bytes) / serd_node_align))
+ : NULL;
+}
+
+static const SerdNode*
serd_node_get_meta_c(const SerdNode* node)
{
return node + 1 + (serd_node_pad_size(node->n_bytes) / serd_node_align);
@@ -303,6 +311,26 @@ serd_node_equals(const SerdNode* a, const SerdNode* b)
return false;
}
+int
+serd_node_compare(const SerdNode* a, const SerdNode* b)
+{
+ if (a == b) {
+ return 0;
+ } else if (!a || !b) {
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
+ } else if (a->type != b->type) {
+ return a->type - b->type;
+ }
+
+ const int cmp = strcmp(serd_node_get_string(a), serd_node_get_string(b));
+ if (cmp) {
+ return cmp;
+ }
+
+ return serd_node_compare(serd_node_maybe_get_meta_c(a),
+ serd_node_maybe_get_meta_c(b));
+}
+
static size_t
serd_uri_string_length(const SerdURI* uri)
{