[libsoup] SoupURI: add SOUP_URI_IS_VALID() and use it for basic precondition checks
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] SoupURI: add SOUP_URI_IS_VALID() and use it for basic precondition checks
- Date: Mon, 6 Feb 2012 22:14:40 +0000 (UTC)
commit 675979d4aa6a72d8415294f989aeb20a6eae2ab6
Author: Simon McVittie <simon mcvittie collabora co uk>
Date: Fri Feb 3 14:13:32 2012 +0000
SoupURI: add SOUP_URI_IS_VALID() and use it for basic precondition checks
In this patch, field setters don't have precondition checks for the
validity of the URI object itself, only a non-NULL check, to avoid
breaking existing code if it calls soup_uri_new (NULL) and then sets
fields in an unexpected order:
uri = soup_uri_new (NULL); /* uri is invalid */
soup_uri_set_host (uri, "www.google.com");
soup_uri_set_query (uri, "q=badgers");
soup_uri_set_scheme (uri, "http"); /* still invalid... */
soup_uri_set_path (uri, "/search"); /* finally valid */
Also annotate nullable setter parameters as (allow-none), to justify
why they don't have a precondition check.
Signed-off-by: Simon McVittie <simon mcvittie collabora co uk>
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=667637
Bug-NB: NB#294977
libsoup/soup-uri.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-------
libsoup/soup-uri.h | 1 +
2 files changed, 89 insertions(+), 13 deletions(-)
---
diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c
index f53decd..0e4c31c 100644
--- a/libsoup/soup-uri.c
+++ b/libsoup/soup-uri.c
@@ -81,6 +81,21 @@
**/
/**
+ * SOUP_URI_IS_VALID:
+ * @uri: a #SoupURI
+ *
+ * Tests whether @uri is a valid #SoupURI; that is, that it is non-%NULL
+ * and its @scheme and @path members are also non-%NULL.
+ *
+ * This macro does not check whether http and https URIs have a non-%NULL
+ * @host member.
+ *
+ * Return value: %TRUE if @uri is valid for use.
+ *
+ * Since: 2.38
+ **/
+
+/**
* SOUP_URI_VALID_FOR_HTTP:
* @uri: a #SoupURI
*
@@ -148,6 +163,9 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string)
gboolean remove_dot_segments = TRUE;
int len;
+ g_return_val_if_fail (base == NULL || SOUP_URI_IS_VALID (base), NULL);
+ g_return_val_if_fail (uri_string != NULL, NULL);
+
/* First some cleanup steps (which are supposed to all be no-ops,
* but...). Skip initial whitespace, strip out internal tabs and
* line breaks, and ignore trailing whitespace.
@@ -428,7 +446,7 @@ soup_uri_to_string (SoupURI *uri, gboolean just_path_and_query)
GString *str;
char *return_result;
- g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
/* IF YOU CHANGE ANYTHING IN THIS FUNCTION, RUN
* tests/uri-parsing AFTERWARD.
@@ -487,7 +505,7 @@ soup_uri_copy (SoupURI *uri)
{
SoupURI *dup;
- g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
dup = g_slice_new0 (SoupURI);
dup->scheme = uri->scheme;
@@ -524,6 +542,9 @@ parts_equal (const char *one, const char *two, gboolean insensitive)
gboolean
soup_uri_equal (SoupURI *uri1, SoupURI *uri2)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri1), FALSE);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri2), FALSE);
+
if (uri1->scheme != uri2->scheme ||
uri1->port != uri2->port ||
!parts_equal (uri1->user, uri2->user, FALSE) ||
@@ -591,6 +612,8 @@ soup_uri_encode (const char *part, const char *escape_extra)
GString *str;
char *encoded;
+ g_return_val_if_fail (part != NULL, NULL);
+
str = g_string_new (NULL);
append_uri_encoded (str, part, escape_extra);
encoded = str->str;
@@ -608,6 +631,8 @@ uri_decoded_copy (const char *part, int length)
unsigned char *s, *d;
char *decoded = g_strndup (part, length);
+ g_return_val_if_fail (part != NULL, NULL);
+
s = d = (unsigned char *)decoded;
do {
if (*s == '%') {
@@ -640,6 +665,8 @@ uri_decoded_copy (const char *part, int length)
char *
soup_uri_decode (const char *part)
{
+ g_return_val_if_fail (part != NULL, NULL);
+
return uri_decoded_copy (part, strlen (part));
}
@@ -727,6 +754,8 @@ uri_normalized_copy (const char *part, int length,
char *
soup_uri_normalize (const char *part, const char *unescape_extra)
{
+ g_return_val_if_fail (part != NULL, NULL);
+
return uri_normalized_copy (part, strlen (part), unescape_extra);
}
@@ -744,6 +773,9 @@ soup_uri_normalize (const char *part, const char *unescape_extra)
gboolean
soup_uri_uses_default_port (SoupURI *uri)
{
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), FALSE);
+
return uri->port == soup_scheme_default_port (uri->scheme);
}
@@ -774,6 +806,8 @@ soup_uri_uses_default_port (SoupURI *uri)
const char *
soup_uri_get_scheme (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->scheme;
}
@@ -788,6 +822,9 @@ soup_uri_get_scheme (SoupURI *uri)
void
soup_uri_set_scheme (SoupURI *uri, const char *scheme)
{
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (scheme != NULL);
+
uri->scheme = soup_uri_parse_scheme (scheme, strlen (scheme));
uri->port = soup_scheme_default_port (uri->scheme);
}
@@ -805,19 +842,23 @@ soup_uri_set_scheme (SoupURI *uri, const char *scheme)
const char *
soup_uri_get_user (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->user;
}
/**
* soup_uri_set_user:
* @uri: a #SoupURI
- * @user: the username, or %NULL
+ * @user: (allow-none): the username, or %NULL
*
* Sets @uri's user to @user.
**/
void
soup_uri_set_user (SoupURI *uri, const char *user)
{
+ g_return_if_fail (uri != NULL);
+
g_free (uri->user);
uri->user = g_strdup (user);
}
@@ -835,19 +876,23 @@ soup_uri_set_user (SoupURI *uri, const char *user)
const char *
soup_uri_get_password (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->password;
}
/**
* soup_uri_set_password:
* @uri: a #SoupURI
- * @password: the password, or %NULL
+ * @password: (allow-none): the password, or %NULL
*
* Sets @uri's password to @password.
**/
void
soup_uri_set_password (SoupURI *uri, const char *password)
{
+ g_return_if_fail (uri != NULL);
+
g_free (uri->password);
uri->password = g_strdup (password);
}
@@ -865,23 +910,29 @@ soup_uri_set_password (SoupURI *uri, const char *password)
const char *
soup_uri_get_host (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->host;
}
/**
* soup_uri_set_host:
* @uri: a #SoupURI
- * @host: the hostname or IP address, or %NULL
+ * @host: (allow-none): the hostname or IP address, or %NULL
*
* Sets @uri's host to @host.
*
* If @host is an IPv6 IP address, it should not include the brackets
* required by the URI syntax; they will be added automatically when
* converting @uri to a string.
+ *
+ * http and https URIs should not have a %NULL @host.
**/
void
soup_uri_set_host (SoupURI *uri, const char *host)
{
+ g_return_if_fail (uri != NULL);
+
g_free (uri->host);
uri->host = g_strdup (host);
}
@@ -899,6 +950,8 @@ soup_uri_set_host (SoupURI *uri, const char *host)
guint
soup_uri_get_port (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), 0);
+
return uri->port;
}
@@ -913,6 +966,8 @@ soup_uri_get_port (SoupURI *uri)
void
soup_uri_set_port (SoupURI *uri, guint port)
{
+ g_return_if_fail (uri != NULL);
+
uri->port = port;
}
@@ -929,19 +984,24 @@ soup_uri_set_port (SoupURI *uri, guint port)
const char *
soup_uri_get_path (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->path;
}
/**
* soup_uri_set_path:
* @uri: a #SoupURI
- * @path: the path
+ * @path: the non-%NULL path
*
* Sets @uri's path to @path.
**/
void
soup_uri_set_path (SoupURI *uri, const char *path)
{
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (path != NULL);
+
g_free (uri->path);
uri->path = g_strdup (path);
}
@@ -959,19 +1019,23 @@ soup_uri_set_path (SoupURI *uri, const char *path)
const char *
soup_uri_get_query (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->query;
}
/**
* soup_uri_set_query:
* @uri: a #SoupURI
- * @query: the query
+ * @query: (allow-none): the query
*
* Sets @uri's query to @query.
**/
void
soup_uri_set_query (SoupURI *uri, const char *query)
{
+ g_return_if_fail (uri != NULL);
+
g_free (uri->query);
uri->query = g_strdup (query);
}
@@ -988,6 +1052,8 @@ soup_uri_set_query (SoupURI *uri, const char *query)
void
soup_uri_set_query_from_form (SoupURI *uri, GHashTable *form)
{
+ g_return_if_fail (uri != NULL);
+
g_free (uri->query);
uri->query = soup_form_encode_hash (form);
}
@@ -1010,6 +1076,8 @@ soup_uri_set_query_from_fields (SoupURI *uri,
{
va_list args;
+ g_return_if_fail (uri != NULL);
+
g_free (uri->query);
va_start (args, first_field);
uri->query = soup_form_encode_valist (first_field, args);
@@ -1029,19 +1097,23 @@ soup_uri_set_query_from_fields (SoupURI *uri,
const char *
soup_uri_get_fragment (SoupURI *uri)
{
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
+
return uri->fragment;
}
/**
* soup_uri_set_fragment:
* @uri: a #SoupURI
- * @fragment: the fragment
+ * @fragment: (allow-none): the fragment
*
* Sets @uri's fragment to @fragment.
**/
void
soup_uri_set_fragment (SoupURI *uri, const char *fragment)
{
+ g_return_if_fail (uri != NULL);
+
g_free (uri->fragment);
uri->fragment = g_strdup (fragment);
}
@@ -1061,7 +1133,7 @@ soup_uri_copy_host (SoupURI *uri)
{
SoupURI *dup;
- g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL);
dup = soup_uri_new (NULL);
dup->scheme = uri->scheme;
@@ -1074,7 +1146,7 @@ soup_uri_copy_host (SoupURI *uri)
/**
* soup_uri_host_hash:
- * @key: (type Soup.URI): a #SoupURI
+ * @key: (type Soup.URI): a #SoupURI with a non-%NULL @host member
*
* Hashes @key, considering only the scheme, host, and port.
*
@@ -1087,7 +1159,8 @@ soup_uri_host_hash (gconstpointer key)
{
const SoupURI *uri = key;
- g_return_val_if_fail (uri != NULL && uri->host != NULL, 0);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (uri), 0);
+ g_return_val_if_fail (uri->host != NULL, 0);
return GPOINTER_TO_UINT (uri->scheme) + uri->port +
soup_str_case_hash (uri->host);
@@ -1095,8 +1168,8 @@ soup_uri_host_hash (gconstpointer key)
/**
* soup_uri_host_equal:
- * @v1: (type Soup.URI): a #SoupURI
- * @v2: (type Soup.URI): a #SoupURI
+ * @v1: (type Soup.URI): a #SoupURI with a non-%NULL @host member
+ * @v2: (type Soup.URI): a #SoupURI with a non-%NULL @host member
*
* Compares @v1 and @v2, considering only the scheme, host, and port.
*
@@ -1112,6 +1185,8 @@ soup_uri_host_equal (gconstpointer v1, gconstpointer v2)
const SoupURI *two = v2;
g_return_val_if_fail (one != NULL && two != NULL, one == two);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (one), FALSE);
+ g_return_val_if_fail (SOUP_URI_IS_VALID (two), FALSE);
g_return_val_if_fail (one->host != NULL && two->host != NULL, one->host == two->host);
if (one->scheme != two->scheme)
diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h
index a5c54a6..b851dbe 100644
--- a/libsoup/soup-uri.h
+++ b/libsoup/soup-uri.h
@@ -97,6 +97,7 @@ guint soup_uri_host_hash (gconstpointer key);
gboolean soup_uri_host_equal (gconstpointer v1,
gconstpointer v2);
+#define SOUP_URI_IS_VALID(uri) ((uri) && (uri)->scheme && (uri)->path)
#define SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host && (uri)->path)
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]