Mercurial > geeqie.yaz
annotate src/uri_utils.c @ 1527:12b0eeb5d528
Nest new keywords inside existing
It is boring to first add a bunch of keywords and then move them to the
new location. It is more natural to add them as child to existing ons.
author | mow |
---|---|
date | Mon, 06 Apr 2009 23:59:54 +0000 |
parents | 67b40740122e |
children |
rev | line source |
---|---|
904 | 1 /* |
2 * Geeqie | |
1284 | 3 * Copyright (C) 2008 - 2009 The Geeqie Team |
904 | 4 * |
5 * Authors: John Ellis, Vladimir Nadvornik, Laurent Monin | |
6 * | |
7 * | |
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! | |
11 */ | |
12 | |
13 #include "main.h" | |
14 #include "uri_utils.h" | |
15 | |
16 #include "filedata.h" | |
17 #include "ui_fileops.h" | |
18 | |
19 /* | |
20 *----------------------------------------------------------------------------- | |
21 * drag and drop uri utils | |
22 *----------------------------------------------------------------------------- | |
23 */ | |
24 | |
25 /* the following characters are allowed to be unencoded for pathnames: | |
26 * $ & + , / : = @ | |
27 */ | |
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 */ | |
48 }; | |
49 | |
50 static gchar *hex_char = "0123456789ABCDEF"; | |
51 | |
1452 | 52 static gboolean escape_test(guchar c) |
904 | 53 { |
54 if (c < 32 || c > 127) return TRUE; | |
55 return (escape_char_list[c] != 0); | |
56 } | |
57 | |
58 static const gchar *escape_code(guchar c) | |
59 { | |
60 static gchar text[4]; | |
61 | |
62 text[0] = '%'; | |
63 text[1] = hex_char[c>>4]; | |
64 text[2] = hex_char[c%16]; | |
65 text[3] = '\0'; | |
66 | |
67 return text; | |
68 } | |
69 | |
70 gchar *uri_text_escape(const gchar *text) | |
71 { | |
72 GString *string; | |
73 gchar *result; | |
74 const gchar *p; | |
75 | |
76 if (!text) return NULL; | |
77 | |
78 string = g_string_new(""); | |
79 | |
80 p = text; | |
81 while (*p != '\0') | |
82 { | |
83 if (escape_test(*p)) | |
84 { | |
85 g_string_append(string, escape_code(*p)); | |
86 } | |
87 else | |
88 { | |
89 g_string_append_c(string, *p); | |
90 } | |
91 p++; | |
92 } | |
93 | |
94 result = string->str; | |
95 g_string_free(string, FALSE); | |
96 | |
97 /* dropped filenames are expected to be utf-8 compatible */ | |
98 if (!g_utf8_validate(result, -1, NULL)) | |
99 { | |
100 gchar *tmp; | |
101 | |
102 tmp = g_locale_to_utf8(result, -1, NULL, NULL, NULL); | |
103 if (tmp) | |
104 { | |
105 g_free(result); | |
106 result = tmp; | |
107 } | |
108 } | |
109 | |
110 return result; | |
111 } | |
112 | |
113 /* this operates on the passed string, decoding escaped characters */ | |
114 void uri_text_decode(gchar *text) | |
115 { | |
116 if (strchr(text, '%')) | |
117 { | |
118 gchar *w; | |
119 gchar *r; | |
120 | |
121 w = r = text; | |
122 | |
123 while (*r != '\0') | |
124 { | |
125 if (*r == '%' && *(r + 1) != '\0' && *(r + 2) != '\0') | |
126 { | |
127 gchar t[3]; | |
128 gint n; | |
129 | |
130 r++; | |
131 t[0] = *r; | |
132 r++; | |
133 t[1] = *r; | |
134 t[2] = '\0'; | |
135 n = (gint)strtol(t, NULL, 16); | |
136 if (n > 0 && n < 256) | |
137 { | |
138 *w = (gchar)n; | |
139 } | |
140 else | |
141 { | |
142 /* invalid number, rewind and ignore this escape */ | |
143 r -= 2; | |
144 *w = *r; | |
145 } | |
146 } | |
147 else if (w != r) | |
148 { | |
149 *w = *r; | |
150 } | |
151 r++; | |
152 w++; | |
153 } | |
154 if (*w != '\0') *w = '\0'; | |
155 } | |
156 } | |
157 | |
158 static void uri_list_parse_encoded_chars(GList *list) | |
159 { | |
160 GList *work = list; | |
161 | |
162 while (work) | |
163 { | |
164 gchar *text = work->data; | |
165 | |
166 uri_text_decode(text); | |
167 | |
168 work = work->next; | |
169 } | |
170 } | |
171 | |
1452 | 172 GList *uri_list_from_text(gchar *data, gboolean files_only) |
904 | 173 { |
174 GList *list = NULL; | |
175 gint b, e; | |
176 | |
177 b = e = 0; | |
178 | |
179 while (data[b] != '\0') | |
180 { | |
181 while (data[e] != '\r' && data[e] != '\n' && data[e] != '\0') e++; | |
182 if (strncmp(data + b, "file:", 5) == 0) | |
183 { | |
184 gchar *path; | |
185 b += 5; | |
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)); | |
189 g_free(path); | |
190 } | |
191 else if (!files_only && strncmp(data + b, "http:", 5) == 0) | |
192 { | |
193 list = g_list_append(list, g_strndup(data + b, e - b)); | |
194 } | |
195 else if (!files_only && strncmp(data + b, "ftp:", 3) == 0) | |
196 { | |
197 list = g_list_append(list, g_strndup(data + b, e - b)); | |
198 } | |
199 while (data[e] == '\r' || data[e] == '\n') e++; | |
200 b = e; | |
201 } | |
202 | |
203 uri_list_parse_encoded_chars(list); | |
204 | |
205 return list; | |
206 } | |
207 | |
1452 | 208 GList *uri_filelist_from_text(gchar *data, gboolean files_only) |
904 | 209 { |
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); | |
213 return filelist; | |
214 } | |
215 | |
1452 | 216 gchar *uri_text_from_list(GList *list, gint *len, gboolean plain_text) |
904 | 217 { |
218 gchar *uri_text = NULL; | |
219 GString *string; | |
220 GList *work; | |
221 | |
222 if (!list) | |
223 { | |
224 if (len) *len = 0; | |
225 return NULL; | |
226 } | |
227 | |
228 string = g_string_new(""); | |
229 | |
230 work = list; | |
231 while (work) | |
232 { | |
233 const gchar *name8; /* dnd filenames are in utf-8 */ | |
234 | |
235 name8 = work->data; | |
236 | |
237 if (!plain_text) | |
238 { | |
239 gchar *escaped; | |
240 | |
241 escaped = uri_text_escape(name8); | |
242 g_string_append(string, "file:"); | |
243 g_string_append(string, escaped); | |
244 g_free(escaped); | |
245 | |
246 g_string_append(string, "\r\n"); | |
247 } | |
248 else | |
249 { | |
250 g_string_append(string, name8); | |
251 if (work->next) g_string_append(string, "\n"); | |
252 } | |
253 | |
254 work = work->next; | |
255 } | |
256 | |
257 uri_text = string->str; | |
258 if (len) *len = string->len; | |
259 g_string_free(string, FALSE); | |
260 | |
261 return uri_text; | |
262 } | |
263 | |
1452 | 264 gchar *uri_text_from_filelist(GList *list, gint *len, gboolean plain_text) |
904 | 265 { |
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); | |
269 return ret; | |
270 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
904
diff
changeset
|
271 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |