Mercurial > geeqie
annotate src/uri_utils.c @ 1367:fe4da037be21
When g_new0() is used, drop redundant initializations to NULL, FALSE or 0, second pass.
| author | zas_ |
|---|---|
| date | Sun, 01 Mar 2009 23:14:19 +0000 |
| parents | 8b89e3ff286b |
| children | 67b40740122e |
| 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 | |
| 52 static gint escape_test(guchar c) | |
| 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 | |
| 172 GList *uri_list_from_text(gchar *data, gint files_only) | |
| 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 | |
| 208 GList *uri_filelist_from_text(gchar *data, gint files_only) | |
| 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 | |
| 216 gchar *uri_text_from_list(GList *list, gint *len, gint plain_text) | |
| 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 | |
| 264 gchar *uri_text_from_filelist(GList *list, gint *len, gint plain_text) | |
| 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: */ |
