From 9b580f1a46571424e85b5fd9f41cb32df92ca7e0 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 20 Dec 2018 13:02:24 -0500 Subject: Add serd_node_compare() --- serd/serd.h | 11 +++++++++++ src/node.c | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/serd/serd.h b/serd/serd.h index e9484ec9..aaf66549 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -642,6 +642,17 @@ SERD_API 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. */ diff --git a/src/node.c b/src/node.c index 9851a6a7..20312815 100644 --- a/src/node.c +++ b/src/node.c @@ -65,6 +65,14 @@ serd_node_pad_size(const size_t n_bytes) return size; } +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) { @@ -303,6 +311,23 @@ 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 : 1; + } else if (a->type != b->type) { + return (a->type < b->type) ? -1 : 1; + } + + const int cmp = strcmp(serd_node_get_string(a), serd_node_get_string(b)); + return cmp ? cmp + : 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) { -- cgit v1.2.1