aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/serd/serd.h12
-rw-r--r--src/node.c25
2 files changed, 37 insertions, 0 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h
index 6aeb9138..4cf00f02 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -1033,6 +1033,18 @@ serd_node_equals(const SerdNode* SERD_NULLABLE a,
const SerdNode* SERD_NULLABLE 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_PURE_API
+int
+serd_node_compare(const SerdNode* SERD_NULLABLE a,
+ const SerdNode* SERD_NULLABLE b);
+
+/**
@}
@defgroup serd_event Event Handlers
@{
diff --git a/src/node.c b/src/node.c
index 4c76ed9b..268b53af 100644
--- a/src/node.c
+++ b/src/node.c
@@ -436,6 +436,31 @@ serd_node_equals(const SerdNode* a, const SerdNode* b)
return serd_node_total_size(b) == a_size && !memcmp(a, b, a_size);
}
+int
+serd_node_compare(const SerdNode* a, const SerdNode* b)
+{
+ if (a == b) {
+ return 0;
+ }
+
+ if (!a) {
+ return -1;
+ }
+
+ if (!b) {
+ return 1;
+ }
+
+ if (a->type != b->type) {
+ return (a->type < b->type) ? -1 : 1;
+ }
+
+ const int cmp = strcmp(serd_node_string(a), serd_node_string(b));
+ return cmp ? cmp
+ : serd_node_compare(serd_node_maybe_get_meta_c(a),
+ serd_node_maybe_get_meta_c(b));
+}
+
SerdNode*
serd_new_uri(const SerdStringView str)
{