aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-03-29 07:28:19 -0400
committerDavid Robillard <d@drobilla.net>2023-12-02 16:27:02 -0500
commitfff826f406e0b9975fd8672041e50dd1a342339f (patch)
tree03a22b89b83a8b26fdf18dd8700e51833b488d81 /include
parent94d3433dcf0e77d2c867c9a2dd6928acfea4184c (diff)
downloadserd-fff826f406e0b9975fd8672041e50dd1a342339f.tar.gz
serd-fff826f406e0b9975fd8672041e50dd1a342339f.tar.bz2
serd-fff826f406e0b9975fd8672041e50dd1a342339f.zip
Simplify URI API and implementation
Diffstat (limited to 'include')
-rw-r--r--include/serd/node.h43
-rw-r--r--include/serd/uri.h125
2 files changed, 89 insertions, 79 deletions
diff --git a/include/serd/node.h b/include/serd/node.h
index 1c64b6b9..b95891c9 100644
--- a/include/serd/node.h
+++ b/include/serd/node.h
@@ -112,20 +112,16 @@ serd_new_substring(SerdNodeType type,
size_t len);
/**
- Create a new URI node from a node.
+ Create a new URI node from a parsed URI.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_uri_from_node(const SerdNode* SERD_NONNULL uri_node,
- const SerdURIView* SERD_NULLABLE base,
- SerdURIView* SERD_NULLABLE out);
+serd_new_parsed_uri(SerdURIView uri);
/**
Create a new URI node from a string.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_uri_from_string(const char* SERD_NULLABLE str,
- const SerdURIView* SERD_NULLABLE base,
- SerdURIView* SERD_NULLABLE out);
+serd_new_uri(const char* SERD_NONNULL str);
/**
Create a new file URI node from a file system path and optional hostname.
@@ -142,39 +138,6 @@ serd_new_file_uri(const char* SERD_NONNULL path,
SerdURIView* SERD_NULLABLE out);
/**
- Create a new node by serialising `uri` into a new string.
-
- @param uri The URI to serialise.
-
- @param base Base URI to resolve `uri` against (or NULL for no resolution).
-
- @param out Set to the parsing of the new URI (i.e. points only to
- memory owned by the new returned node).
-*/
-SERD_API SerdNode* SERD_ALLOCATED
-serd_new_uri(const SerdURIView* SERD_NONNULL uri,
- const SerdURIView* SERD_NULLABLE base,
- SerdURIView* SERD_NULLABLE out);
-
-/**
- Create a new node by serialising `uri` into a new relative URI.
-
- @param uri The URI to serialise.
-
- @param base Base URI to make `uri` relative to, if possible.
-
- @param root Root URI for resolution (see serd_uri_serialise_relative()).
-
- @param out Set to the parsing of the new URI (i.e. points only to
- memory owned by the new returned node).
-*/
-SERD_API SerdNode* SERD_ALLOCATED
-serd_new_relative_uri(const SerdURIView* SERD_NONNULL uri,
- const SerdURIView* SERD_NULLABLE base,
- const SerdURIView* SERD_NULLABLE root,
- SerdURIView* SERD_NULLABLE out);
-
-/**
Create a new node by serialising `d` into an xsd:decimal string.
The resulting node will always contain a '.', start with a digit, and end
diff --git a/include/serd/uri.h b/include/serd/uri.h
index 06cb97fb..7b5529dc 100644
--- a/include/serd/uri.h
+++ b/include/serd/uri.h
@@ -5,7 +5,6 @@
#define SERD_URI_H
#include "serd/attributes.h"
-#include "serd/status.h"
#include "serd/stream.h"
#include "serd/string_view.h"
@@ -21,19 +20,30 @@ SERD_BEGIN_DECLS
*/
/**
- A parsed URI.
-
- This struct directly refers to slices in other strings, it does not own any
- memory itself. This allows some URI operations like resolution to be done
- in-place without allocating memory.
+ A parsed view of a URI.
+
+ This representation is designed for fast streaming. It makes it possible to
+ create relative URI references or resolve them into absolute URIs in-place
+ without any string allocation.
+
+ Each component refers to slices in other strings, so a URI view must outlive
+ any strings it was parsed from. Note that the components are not
+ necessarily null-terminated.
+
+ The scheme, authority, path, query, and fragment simply point to the string
+ value of those components, not including any delimiters. The path_prefix is
+ a special component for storing relative or resolved paths. If it points to
+ a string (usually a base URI the URI was resolved against), then this string
+ is prepended to the path. Otherwise, the length is interpreted as the
+ number of up-references ("../") that must be prepended to the path.
*/
typedef struct {
- SerdStringView scheme; ///< Scheme
- SerdStringView authority; ///< Authority
- SerdStringView path_base; ///< Path prefix if relative
- SerdStringView path; ///< Path suffix
- SerdStringView query; ///< Query
- SerdStringView fragment; ///< Fragment
+ SerdStringView scheme; ///< Scheme
+ SerdStringView authority; ///< Authority
+ SerdStringView path_prefix; ///< Path prefix for relative/resolved paths
+ SerdStringView path; ///< Path suffix
+ SerdStringView query; ///< Query
+ SerdStringView fragment; ///< Fragment
} SerdURIView;
static const SerdURIView SERD_URI_NULL =
@@ -46,49 +56,86 @@ static const SerdURIView SERD_URI_NULL =
@param uri A file URI.
@param hostname If non-NULL, set to the hostname, if present.
- @return The path component of the URI.
+ @return A newly-allocated filesystem path.
*/
-SERD_API char* SERD_NULLABLE
-serd_file_uri_parse(const char* SERD_NONNULL uri,
+SERD_API char* SERD_ALLOCATED
+serd_parse_file_uri(const char* SERD_NONNULL uri,
char* SERD_NONNULL* SERD_NULLABLE hostname);
-/// Return true iff `utf8` starts with a valid URI scheme
+/// Return true iff `string` starts with a valid URI scheme
SERD_PURE_API bool
-serd_uri_string_has_scheme(const char* SERD_NULLABLE utf8);
+serd_uri_string_has_scheme(const char* SERD_NONNULL string);
-/// Parse `utf8`, writing result to `out`
-SERD_API SerdStatus
-serd_uri_parse(const char* SERD_NONNULL utf8, SerdURIView* SERD_NONNULL out);
+/// Parse `string` and return a URI view that points into it
+SERD_PURE_API SerdURIView
+serd_parse_uri(const char* SERD_NONNULL string);
/**
- Set target `t` to reference `r` resolved against `base`.
+ Return reference `r` resolved against `base`.
+
+ This will make `r` an absolute URI if possible.
@see [RFC3986 5.2.2](http://tools.ietf.org/html/rfc3986#section-5.2.2)
+
+ @param r URI reference to make absolute, for example "child/path".
+
+ @param base Base URI, for example "http://example.org/base/".
+
+ @return An absolute URI, for example "http://example.org/base/child/path",
+ or `r` if it is not a URI reference that can be resolved against `base`.
*/
-SERD_API void
-serd_uri_resolve(const SerdURIView* SERD_NONNULL r,
- const SerdURIView* SERD_NONNULL base,
- SerdURIView* SERD_NONNULL t);
+SERD_PURE_API SerdURIView
+serd_resolve_uri(SerdURIView r, SerdURIView base);
-/// Serialise `uri` with a series of calls to `sink`
-SERD_API size_t
-serd_uri_serialise(const SerdURIView* SERD_NONNULL uri,
- SerdSink SERD_NONNULL sink,
- void* SERD_NONNULL stream);
+/**
+ Return `r` as a reference relative to `base` if possible.
+
+ @see [RFC3986 5.2.2](http://tools.ietf.org/html/rfc3986#section-5.2.2)
+
+ @param r URI to make relative, for example
+ "http://example.org/base/child/path".
+
+ @param base Base URI, for example "http://example.org/base".
+
+ @return A relative URI reference, for example "child/path", `r` if it can
+ not be made relative to `base`, or a null URI if `r` could be made relative
+ to base, but the path prefix is already being used (most likely because `r`
+ was previously a relative URI reference that was resolved against some
+ base).
+*/
+SERD_PURE_API SerdURIView
+serd_relative_uri(SerdURIView r, SerdURIView base);
+
+/**
+ Return whether `r` can be written as a reference relative to `base`.
+
+ For example, with `base` "http://example.org/base/", this returns true if
+ `r` is also "http://example.org/base/", or something like
+ "http://example.org/base/child" ("child")
+ "http://example.org/base/child/grandchild#fragment"
+ ("child/grandchild#fragment"),
+ "http://example.org/base/child/grandchild?query" ("child/grandchild?query"),
+ and so on.
+
+ @return True if `r` and `base` are equal or if `r` is a child of `base`.
+*/
+SERD_PURE_API bool
+serd_uri_is_within(SerdURIView r, SerdURIView base);
/**
- Serialise `uri` relative to `base` with a series of calls to `sink`
+ Write `uri` as a string to `sink`.
+
+ This will call `sink` several times to emit the URI.
- The `uri` is written as a relative URI iff if it a child of `base` and
- `root`. The optional `root` parameter must be a prefix of `base` and can be
- used keep up-references ("../") within a certain namespace.
+ @param uri URI to write as a string.
+ @param sink Sink to write string output to.
+ @param stream Opaque user argument to pass to `sink`.
+ @return The number of bytes written.
*/
SERD_API size_t
-serd_uri_serialise_relative(const SerdURIView* SERD_NONNULL uri,
- const SerdURIView* SERD_NULLABLE base,
- const SerdURIView* SERD_NULLABLE root,
- SerdSink SERD_NONNULL sink,
- void* SERD_NONNULL stream);
+serd_write_uri(SerdURIView uri,
+ SerdSink SERD_NONNULL sink,
+ void* SERD_NONNULL stream);
/**
@}