3 * Copyright (C) 2008 - 2012 The Geeqie Team
5 * Authors: John Ellis, Vladimir Nadvornik, Laurent Monin
8 * This software is released under the GNU General Public License (GNU GPL).
9 * Please read the included file COPYING for more information.
10 * This software comes with no warranty of any kind, use at your own risk!
14 #include "uri_utils.h"
17 #include "ui_fileops.h"
20 *-----------------------------------------------------------------------------
21 * drag and drop uri utils
22 *-----------------------------------------------------------------------------
25 /* the following characters are allowed to be unencoded for pathnames:
28 static gint escape_char_list[] = {
29 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */
30 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 */
31 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */
32 /* spc ! " # $ % & ' */
33 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, /* 30 */
34 /* ( ) * + , - . / 0 1 */
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 */
36 /* 2 3 4 5 6 7 8 9 : ; */
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 50 */
38 /* < = > ? @ A B C D E */
39 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, /* 60 */
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 */
42 /* Z [ \ ] ^ _ ` a b c */
43 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, /* 90 */
44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 100 */
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 110 */
46 /* x y z { | } ~ del */
47 0, 0, 0, 1, 1, 1, 0, 0 /* 120, 127 is end */
50 static gchar *hex_char = "0123456789ABCDEF";
52 static gboolean escape_test(guchar c)
54 if (c < 32 || c > 127) return TRUE;
55 return (escape_char_list[c] != 0);
58 static const gchar *escape_code(guchar c)
63 text[1] = hex_char[c>>4];
64 text[2] = hex_char[c%16];
70 gchar *uri_text_escape(const gchar *text)
76 if (!text) return NULL;
78 string = g_string_new("");
85 g_string_append(string, escape_code(*p));
89 g_string_append_c(string, *p);
95 g_string_free(string, FALSE);
97 /* dropped filenames are expected to be utf-8 compatible */
98 if (!g_utf8_validate(result, -1, NULL))
102 tmp = g_locale_to_utf8(result, -1, NULL, NULL, NULL);
113 /* this operates on the passed string, decoding escaped characters */
114 void uri_text_decode(gchar *text)
116 if (strchr(text, '%'))
125 if (*r == '%' && *(r + 1) != '\0' && *(r + 2) != '\0')
135 n = (gint)strtol(t, NULL, 16);
136 if (n > 0 && n < 256)
142 /* invalid number, rewind and ignore this escape */
154 if (*w != '\0') *w = '\0';
158 static void uri_list_parse_encoded_chars(GList *list)
164 gchar *text = work->data;
166 uri_text_decode(text);
172 GList *uri_list_from_text(gchar *data, gboolean files_only)
179 while (data[b] != '\0')
181 while (data[e] != '\r' && data[e] != '\n' && data[e] != '\0') e++;
182 if (strncmp(data + b, "file:", 5) == 0)
186 while (data[b] == '/' && data[b+1] == '/') b++;
187 path = g_strndup(data + b, e - b);
188 list = g_list_append(list, path_to_utf8(path));
191 else if (!files_only && strncmp(data + b, "http:", 5) == 0)
193 list = g_list_append(list, g_strndup(data + b, e - b));
195 else if (!files_only && strncmp(data + b, "ftp:", 3) == 0)
197 list = g_list_append(list, g_strndup(data + b, e - b));
199 while (data[e] == '\r' || data[e] == '\n') e++;
203 uri_list_parse_encoded_chars(list);
208 GList *uri_filelist_from_text(gchar *data, gboolean files_only)
210 GList *path_list = uri_list_from_text(data, files_only);
211 GList *filelist = filelist_from_path_list(path_list);
212 string_list_free(path_list);
216 gchar *uri_text_from_list(GList *list, gint *len, gboolean plain_text)
218 gchar *uri_text = NULL;
228 string = g_string_new("");
233 const gchar *name8; /* dnd filenames are in utf-8 */
241 escaped = uri_text_escape(name8);
242 g_string_append(string, "file:");
243 g_string_append(string, escaped);
246 g_string_append(string, "\r\n");
250 g_string_append(string, name8);
251 if (work->next) g_string_append(string, "\n");
257 uri_text = string->str;
258 if (len) *len = string->len;
259 g_string_free(string, FALSE);
264 gchar *uri_text_from_filelist(GList *list, gint *len, gboolean plain_text)
266 GList *path_list = filelist_to_path_list(list);
267 gchar *ret = uri_text_from_list(path_list, len, plain_text);
268 string_list_free(path_list);
271 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */