From df3926d1c4762009d3bfa437cf115036ec4d1509 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Mon, 20 Apr 2009 13:09:59 +0300 Subject: [PATCH] Fix show directory and file names in other that system encoding symbolsets (with error of recoding). Old behaviour: enrties not show, new behaviour: entries show, but marked as broken files if recoding impossible --- src/strutil.c | 193 ++++++++++++++++++++++++++++---------------------- vfs/vfs.c | 4 +- 2 files changed, 111 insertions(+), 86 deletions(-) diff --git a/src/strutil.c b/src/strutil.c index a403637e1..c3d598497 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -101,109 +101,134 @@ static int _str_convert (GIConv coder, char *string, int size, GString * buffer) { int state; - gchar *tmp_buff; + gchar *tmp_buff = NULL; gssize left; gsize bytes_read, bytes_written; GError *error = NULL; - errno = 0; + if (string == NULL || buffer == NULL) + return ESTR_FAILURE; - if (used_class.is_valid_string (string)) + if (! used_class.is_valid_string (string)) { - state = 0; - if (size < 0) + return ESTR_FAILURE; + } + + state = 0; + if (size < 0) + { + size = strlen (string); + } + else + { + left = strlen (string); + if (left < size) + size = left; + } + + left = size; + + if (coder == (GIConv) (-1)) + return ESTR_FAILURE; + + g_iconv (coder, NULL, NULL, NULL, NULL); + + while (left) + { + tmp_buff = g_convert_with_iconv ((const gchar *) string, + left, + coder, + &bytes_read, + &bytes_written, &error); + if (error) { - size = strlen (string); + switch (error->code) + { + case G_CONVERT_ERROR_NO_CONVERSION: + /* Conversion between the requested character sets is not supported. */ + tmp_buff = g_strnfill (strlen (string), '?'); + g_string_append (buffer, tmp_buff); + g_free (tmp_buff); + g_error_free (error); + error = NULL; + return ESTR_FAILURE; + break; + case G_CONVERT_ERROR_ILLEGAL_SEQUENCE: + /* Invalid byte sequence in conversion input. */ + if (tmp_buff){ + g_string_append (buffer, tmp_buff); + g_free (tmp_buff); + } + if (bytes_read < left) + { + string += bytes_read + 1; + size -= (bytes_read + 1); + left -= (bytes_read + 1); + g_string_append_c (buffer, *(string-1)); + } + else + { + g_error_free (error); + error = NULL; + return ESTR_PROBLEM; + } + state = ESTR_PROBLEM; + break; + case G_CONVERT_ERROR_PARTIAL_INPUT: + /* Partial character sequence at end of input. */ + g_error_free (error); + error = NULL; + g_string_append (buffer, tmp_buff); + g_free (tmp_buff); + if (bytes_read < left) + { + left = left - bytes_read; + tmp_buff = g_strnfill (left, '?'); + g_string_append (buffer, tmp_buff); + g_free (tmp_buff); + } + return ESTR_PROBLEM; + break; + case G_CONVERT_ERROR_BAD_URI: /* Don't know how handle this error :( */ + case G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: /* Don't know how handle this error :( */ + case G_CONVERT_ERROR_FAILED: /* Conversion failed for some reason. */ + default: + g_error_free (error); + error = NULL; + if (tmp_buff){ + g_free (tmp_buff); + tmp_buff = NULL; + } + return ESTR_FAILURE; + } + g_error_free (error); + error = NULL; } else { - left = strlen (string); - if (left < size) - size = left; - } - left = size; - - if (coder == (GIConv) (-1)) - return ESTR_FAILURE; - - g_iconv (coder, NULL, NULL, NULL, NULL); - - while (left) - { - tmp_buff = g_convert_with_iconv ((const gchar *) string, - left, - coder, - &bytes_read, - &bytes_written, &error); - - if (error) + if (tmp_buff != NULL) { - switch (error->code) - { - case G_CONVERT_ERROR_NO_CONVERSION: - /* Conversion between the requested character sets is not supported. */ - tmp_buff = g_strnfill (strlen (string), '?'); + if (*tmp_buff){ g_string_append (buffer, tmp_buff); g_free (tmp_buff); - g_error_free (error); - return ESTR_PROBLEM; - break; - case G_CONVERT_ERROR_ILLEGAL_SEQUENCE: - /* Invalid byte sequence in conversion input. */ - g_string_append (buffer, tmp_buff); - g_string_append (buffer, "?"); - g_free (tmp_buff); - if (bytes_read < left) - { - string += bytes_read + 1; - size -= (bytes_read + 1); - left -= (bytes_read + 1); - } - else - { - g_error_free (error); - return ESTR_PROBLEM; - } - state = ESTR_PROBLEM; - break; - case G_CONVERT_ERROR_PARTIAL_INPUT: - /* Partial character sequence at end of input. */ - g_error_free (error); - g_string_append (buffer, tmp_buff); - g_free (tmp_buff); - if (bytes_read < left) - { - left = left - bytes_read; - tmp_buff = g_strnfill (left, '?'); - g_string_append (buffer, tmp_buff); - g_free (tmp_buff); - } - return ESTR_PROBLEM; - break; - case G_CONVERT_ERROR_BAD_URI: /* Don't know how handle this error :( */ - case G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: /* Don't know how handle this error :( */ - case G_CONVERT_ERROR_FAILED: /* Conversion failed for some reason. */ - default: - g_error_free (error); - if (tmp_buff) - g_free (tmp_buff); - - return ESTR_FAILURE; + string += bytes_read; + left -= bytes_read; + } + else + { + g_free (tmp_buff); + g_string_append (buffer, string); + return state; } - g_error_free (error); } else { - g_string_append (buffer, tmp_buff); - g_free (tmp_buff); - string += bytes_read; - left -= bytes_read; + g_string_append (buffer, string); + return ESTR_PROBLEM; } } - return state; } - else - return ESTR_FAILURE; + return state; } int @@ -233,7 +258,7 @@ str_vfs_convert_from (GIConv coder, char *string, GString * buffer) if (coder == str_cnv_not_convert) { - g_string_append (buffer, string); + g_string_append (buffer, (string)?string:""); result = 0; } else diff --git a/vfs/vfs.c b/vfs/vfs.c index 85fde7c0b..d5cfbf426 100644 --- a/vfs/vfs.c +++ b/vfs/vfs.c @@ -750,13 +750,13 @@ mc_readdir (DIR *dirp) vfs = vfs_op (handle); dirinfo = vfs_info (handle); if (vfs->readdir) { - do { +// do { entry = (*vfs->readdir) (dirinfo->info); if (entry == NULL) return NULL; g_string_set_size(vfs_str_buffer,0); state = str_vfs_convert_from (dirinfo->converter, entry->d_name, vfs_str_buffer); - } while (state != 0); +// } while (state != 0); memcpy (&result, entry, sizeof (struct dirent)); g_strlcpy (result.d_name, vfs_str_buffer->str, NAME_MAX + 1); result.d_reclen = strlen (result.d_name);