diff options
author | Alexander Larsson <alexl@redhat.com> | 2007-11-12 12:22:05 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2007-11-12 12:22:05 +0000 |
commit | 5390fb86582c79939b7a51ef512bd28664bbb1ca (patch) | |
tree | 5a4bb1e7f34929b7ca7e8c0675183f5e884eb702 /client/gvfsuriutils.c | |
parent | 31644982c385c859b9d4b3794b1d842d32aaebd8 (diff) | |
download | gvfs-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.c | 246 |
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); +} |