summaryrefslogtreecommitdiff
path: root/client/gvfsuriutils.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2007-11-12 12:22:05 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-11-12 12:22:05 +0000
commit5390fb86582c79939b7a51ef512bd28664bbb1ca (patch)
tree5a4bb1e7f34929b7ca7e8c0675183f5e884eb702 /client/gvfsuriutils.c
parent31644982c385c859b9d4b3794b1d842d32aaebd8 (diff)
downloadgvfs-5390fb86582c79939b7a51ef512bd28664bbb1ca.tar.gz
Add new functions
2007-11-12 Alexander Larsson <alexl@redhat.com> * common/gmountspec.[ch]: (g_mount_spec_new_from_data): (g_mount_spec_set_with_len): Add new functions * client/Makefile.am: * common/Makefile.am: Update for moved files Build non-shared version of common libs. Ups non-shared common libs in client module. * common/gvfsuriutils.[ch]: Removed. * client/gvfsuriutils.[ch]: Added. Moved uriutils to gvfs (not used by daemon) Re-namespace to g_vfs_* * common/gvfsurimapper.[ch]: Removed. * client/gvfsurimapper.[ch]: Added. Move UriMapper to client lib Remove/Hide use of GMountSpec * client/gdaemonvfs.c: * client/smburi.c: Update to the new APIs * client/gvfsfusedaemon.c: * daemon/gvfsbackendtrash.c: * daemon/gvfsjobqueryfsinfo.c: Fix warnings svn path=/trunk/; revision=1020
Diffstat (limited to 'client/gvfsuriutils.c')
-rw-r--r--client/gvfsuriutils.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/client/gvfsuriutils.c b/client/gvfsuriutils.c
new file mode 100644
index 00000000..78aa850e
--- /dev/null
+++ b/client/gvfsuriutils.c
@@ -0,0 +1,246 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+#include "gvfsuriutils.h"
+#include <string.h>
+#include <stdlib.h>
+
+void
+g_vfs_decoded_uri_free (GDecodedUri *decoded)
+{
+ if (decoded == NULL)
+ return;
+
+ g_free (decoded->scheme);
+ g_free (decoded->query);
+ g_free (decoded->fragment);
+ g_free (decoded->userinfo);
+ g_free (decoded->host);
+ g_free (decoded->path);
+ g_free (decoded);
+}
+
+GDecodedUri *
+g_vfs_decoded_uri_new (void)
+{
+ GDecodedUri *uri;
+
+ uri = g_new0 (GDecodedUri, 1);
+ uri->port = -1;
+
+ return uri;
+}
+
+GDecodedUri *
+g_vfs_decode_uri (const char *uri)
+{
+ GDecodedUri *decoded;
+ const char *p, *in, *hier_part_start, *hier_part_end, *query_start, *fragment_start;
+ char *out;
+ char c;
+
+ /* From RFC 3986 Decodes:
+ * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+ */
+
+ p = uri;
+
+ /* Decode scheme:
+ scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ */
+
+ if (!g_ascii_isalpha (*p))
+ return NULL;
+
+ while (1)
+ {
+ c = *p++;
+
+ if (c == ':')
+ break;
+
+ if (!(g_ascii_isalnum(c) ||
+ c == '+' ||
+ c == '-' ||
+ c == '.'))
+ return NULL;
+ }
+
+ decoded = g_vfs_decoded_uri_new ();
+
+ decoded->scheme = g_malloc (p - uri);
+ out = decoded->scheme;
+ for (in = uri; in < p - 1; in++)
+ *out++ = g_ascii_tolower (*in);
+ *out = 0;
+
+ hier_part_start = p;
+
+ query_start = strchr (p, '?');
+ if (query_start)
+ {
+ hier_part_end = query_start++;
+ fragment_start = strchr (query_start, '#');
+ if (fragment_start)
+ {
+ decoded->query = g_strndup (query_start, fragment_start - query_start);
+ decoded->fragment = g_strdup (fragment_start+1);
+ }
+ else
+ {
+ decoded->query = g_strdup (query_start);
+ decoded->fragment = NULL;
+ }
+ }
+ else
+ {
+ /* No query */
+ decoded->query = NULL;
+ fragment_start = strchr (p, '#');
+ if (fragment_start)
+ {
+ hier_part_end = fragment_start++;
+ decoded->fragment = g_strdup (fragment_start);
+ }
+ else
+ {
+ hier_part_end = p + strlen (p);
+ decoded->fragment = NULL;
+ }
+ }
+
+ /* 3:
+ hier-part = "//" authority path-abempty
+ / path-absolute
+ / path-rootless
+ / path-empty
+
+ */
+
+ if (hier_part_start[0] == '/' &&
+ hier_part_start[1] == '/')
+ {
+ const char *authority_start, *authority_end;
+ const char *userinfo_start, *userinfo_end;
+ const char *host_start, *host_end;
+ const char *port_start;
+
+ authority_start = hier_part_start + 2;
+ /* authority is always followed by / or nothing */
+ authority_end = memchr (authority_start, '/', hier_part_end - authority_start);
+ if (authority_end == NULL)
+ authority_end = hier_part_end;
+
+ /* 3.2:
+ authority = [ userinfo "@" ] host [ ":" port ]
+ */
+
+ userinfo_end = memchr (authority_start, '@', authority_end - authority_start);
+ if (userinfo_end)
+ {
+ userinfo_start = authority_start;
+ decoded->userinfo = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL);
+ if (decoded->userinfo == NULL)
+ {
+ g_vfs_decoded_uri_free (decoded);
+ return NULL;
+ }
+ host_start = userinfo_end + 1;
+ }
+ else
+ host_start = authority_start;
+
+ port_start = memchr (host_start, ':', authority_end - host_start);
+ if (port_start)
+ {
+ host_end = port_start++;
+
+ decoded->port = atoi(port_start);
+ }
+ else
+ {
+ host_end = authority_end;
+ decoded->port = -1;
+ }
+
+ decoded->host = g_strndup (host_start, host_end - host_start);
+
+ hier_part_start = authority_end;
+ }
+
+ decoded->path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/");
+
+ if (decoded->path == NULL)
+ {
+ g_vfs_decoded_uri_free (decoded);
+ return NULL;
+ }
+
+ return decoded;
+}
+
+char *
+g_vfs_encode_uri (GDecodedUri *decoded, gboolean allow_utf8)
+{
+ GString *uri;
+
+ uri = g_string_new (NULL);
+
+ g_string_append (uri, decoded->scheme);
+ g_string_append (uri, "://");
+
+ if (decoded->host != NULL)
+ {
+ if (decoded->userinfo)
+ {
+ /* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */
+ g_string_append_uri_escaped (uri, decoded->userinfo,
+ G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, allow_utf8);
+ g_string_append_c (uri, '@');
+ }
+
+ g_string_append (uri, decoded->host);
+
+ if (decoded->port != -1)
+ {
+ g_string_append_c (uri, ':');
+ g_string_append_printf (uri, "%d", decoded->port);
+ }
+ }
+
+ g_string_append_uri_escaped (uri, decoded->path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, allow_utf8);
+
+ if (decoded->query)
+ {
+ g_string_append_c (uri, '?');
+ g_string_append (uri, decoded->query);
+ }
+
+ if (decoded->fragment)
+ {
+ g_string_append_c (uri, '#');
+ g_string_append (uri, decoded->fragment);
+ }
+
+ return g_string_free (uri, FALSE);
+}