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
This commit is contained in:
Slava Zanko 2009-04-20 13:09:59 +03:00
parent 26f0e58810
commit df3926d1c4
2 changed files with 111 additions and 86 deletions

View File

@ -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

View File

@ -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);