From b9cc3b642a9365c033c1fa31458d7822b42d0913 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 28 Feb 2021 14:24:24 -0500 Subject: Make serd_uri_string_length() precise and add it to public API --- src/node.c | 27 ++++++--------------------- src/uri.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/node.c b/src/node.c index 9d9d6532..bd306875 100644 --- a/src/node.c +++ b/src/node.c @@ -42,25 +42,6 @@ static const SerdNodeFlags meta_mask = (SERD_HAS_DATATYPE | SERD_HAS_LANGUAGE); static SerdNode* serd_new_from_uri(SerdURIView uri, SerdURIView base); -static size_t -serd_uri_string_length(const SerdURIView* const uri) -{ - size_t len = uri->path_prefix.len; - -#define ADD_LEN(field, n_delims) \ - if ((field).len) { \ - len += (field).len + (n_delims); \ - } - - ADD_LEN(uri->path, 1) // + possible leading `/' - ADD_LEN(uri->scheme, 1) // + trailing `:' - ADD_LEN(uri->authority, 2) // + leading `//' - ADD_LEN(uri->query, 1) // + leading `?' - ADD_LEN(uri->fragment, 1) // + leading `#' - - return len + 2; // + 2 for authority `//' -} - static size_t string_sink(const void* const buf, const size_t size, @@ -462,11 +443,13 @@ serd_new_uri(const SerdStringView str) SerdNode* serd_new_parsed_uri(const SerdURIView uri) { - const size_t len = serd_uri_string_length(&uri); + const size_t len = serd_uri_string_length(uri); SerdNode* const node = serd_node_malloc(len, 0, SERD_URI); char* ptr = serd_node_buffer(node); const size_t actual_len = serd_write_uri(uri, string_sink, &ptr); + assert(actual_len == len); + serd_node_buffer(node)[actual_len] = '\0'; node->length = actual_len; @@ -478,11 +461,13 @@ static SerdNode* serd_new_from_uri(const SerdURIView uri, const SerdURIView base) { const SerdURIView abs_uri = serd_resolve_uri(uri, base); - const size_t len = serd_uri_string_length(&abs_uri); + const size_t len = serd_uri_string_length(abs_uri); SerdNode* node = serd_node_malloc(len, 0, SERD_URI); char* ptr = serd_node_buffer(node); const size_t actual_len = serd_write_uri(abs_uri, string_sink, &ptr); + assert(actual_len == len); + serd_node_buffer(node)[actual_len] = '\0'; node->length = actual_len; diff --git a/src/uri.c b/src/uri.c index 2b7aef17..eb4a2533 100644 --- a/src/uri.c +++ b/src/uri.c @@ -409,6 +409,44 @@ serd_uri_is_within(const SerdURIView uri, const SerdURIView base) return true; } +size_t +serd_uri_string_length(const SerdURIView uri) +{ + size_t len = 0; + + if (uri.scheme.buf) { + len += uri.scheme.len + 1; + } + + if (uri.authority.buf) { + const bool needs_extra_slash = + (uri.authority.len > 0 && uri_path_len(&uri) > 0 && + uri_path_at(&uri, 0) != '/'); + + len += 2 + uri.authority.len + needs_extra_slash; + } + + if (uri.path_prefix.buf) { + len += uri.path_prefix.len; + } else if (uri.path_prefix.len) { + len += 3 * uri.path_prefix.len; + } + + if (uri.path.buf) { + len += uri.path.len; + } + + if (uri.query.buf) { + len += uri.query.len + 1; + } + + if (uri.fragment.buf) { + len += uri.fragment.len; + } + + return len; +} + /// See http://tools.ietf.org/html/rfc3986#section-5.3 size_t serd_write_uri(const SerdURIView uri, -- cgit v1.2.1