mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-02 17:26:17 +01:00
Add fallback mode to GCharsetConverter
This commit is contained in:
parent
4b8382823e
commit
134e9bd84f
@ -36,7 +36,8 @@
|
|||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_FROM_CHARSET,
|
PROP_FROM_CHARSET,
|
||||||
PROP_TO_CHARSET
|
PROP_TO_CHARSET,
|
||||||
|
PROP_USE_FALLBACK
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,6 +64,8 @@ struct _GCharsetConverter
|
|||||||
char *from;
|
char *from;
|
||||||
char *to;
|
char *to;
|
||||||
GIConv iconv;
|
GIConv iconv;
|
||||||
|
gboolean use_fallback;
|
||||||
|
guint n_fallback_errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GCharsetConverter, g_charset_converter, G_TYPE_OBJECT,
|
G_DEFINE_TYPE_WITH_CODE (GCharsetConverter, g_charset_converter, G_TYPE_OBJECT,
|
||||||
@ -108,6 +111,10 @@ g_charset_converter_set_property (GObject *object,
|
|||||||
conv->from = g_value_dup_string (value);
|
conv->from = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_USE_FALLBACK:
|
||||||
|
conv->use_fallback = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -135,6 +142,10 @@ g_charset_converter_get_property (GObject *object,
|
|||||||
g_value_set_string (value, conv->from);
|
g_value_set_string (value, conv->from);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_USE_FALLBACK:
|
||||||
|
g_value_set_boolean (value, conv->use_fallback);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -166,7 +177,15 @@ g_charset_converter_class_init (GCharsetConverterClass *klass)
|
|||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_USE_FALLBACK,
|
||||||
|
g_param_spec_boolean ("use-fallback",
|
||||||
|
P_("Fallback enabled"),
|
||||||
|
P_("Use fallback (of form \\<hexval>) for invalid bytes"),
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -215,6 +234,7 @@ g_charset_converter_reset (GConverter *converter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_iconv (conv->iconv, NULL, NULL, NULL, NULL);
|
g_iconv (conv->iconv, NULL, NULL, NULL, NULL);
|
||||||
|
conv->n_fallback_errors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GConverterResult
|
static GConverterResult
|
||||||
@ -292,8 +312,29 @@ g_charset_converter_convert (GConverter *converter,
|
|||||||
|
|
||||||
case EILSEQ:
|
case EILSEQ:
|
||||||
/* Invalid code sequence */
|
/* Invalid code sequence */
|
||||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
if (conv->use_fallback)
|
||||||
_("Invalid byte sequence in conversion input"));
|
{
|
||||||
|
if (outbuf_size < 3)
|
||||||
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
|
||||||
|
_("Not enough space in destination"));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char hex[] = "0123456789ABCDEF";
|
||||||
|
guint8 v = *(guint8 *)inbuf;
|
||||||
|
guint8 *out = (guint8 *)outbuf;
|
||||||
|
out[0] = '\\';
|
||||||
|
out[1] = hex[(v & 0xf0) >> 4];
|
||||||
|
out[2] = hex[(v & 0x0f) >> 0];
|
||||||
|
*bytes_read = 1;
|
||||||
|
*bytes_written = 3;
|
||||||
|
in_left--;
|
||||||
|
conv->n_fallback_errors++;
|
||||||
|
goto ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
||||||
|
_("Invalid byte sequence in conversion input"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -306,6 +347,7 @@ g_charset_converter_convert (GConverter *converter,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ok:
|
||||||
ret = G_CONVERTER_CONVERTED;
|
ret = G_CONVERTER_CONVERTED;
|
||||||
|
|
||||||
if (in_left == 0 &&
|
if (in_left == 0 &&
|
||||||
@ -319,6 +361,31 @@ g_charset_converter_convert (GConverter *converter,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_charset_converter_set_use_fallback (GCharsetConverter *converter,
|
||||||
|
gboolean use_fallback)
|
||||||
|
{
|
||||||
|
use_fallback = !!use_fallback;
|
||||||
|
|
||||||
|
if (converter->use_fallback != use_fallback)
|
||||||
|
{
|
||||||
|
converter->use_fallback = use_fallback;
|
||||||
|
g_object_notify (G_OBJECT (converter), "use-fallback");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_charset_converter_get_use_fallback (GCharsetConverter *converter)
|
||||||
|
{
|
||||||
|
return converter->use_fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
g_charset_converter_get_num_fallbacks (GCharsetConverter *converter)
|
||||||
|
{
|
||||||
|
return converter->n_fallback_errors;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_charset_converter_iface_init (GConverterIface *iface)
|
g_charset_converter_iface_init (GConverterIface *iface)
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,9 @@ GType g_charset_converter_get_type (void) G_GNUC_CONST;
|
|||||||
GCharsetConverter *g_charset_converter_new (const gchar *to_charset,
|
GCharsetConverter *g_charset_converter_new (const gchar *to_charset,
|
||||||
const gchar *from_charset,
|
const gchar *from_charset,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
void g_charset_converter_set_use_fallback (GCharsetConverter *converter,
|
||||||
|
gboolean use_fallback);
|
||||||
|
gboolean g_charset_converter_get_use_fallback (GCharsetConverter *converter);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user