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 {
|
||||
PROP_0,
|
||||
PROP_FROM_CHARSET,
|
||||
PROP_TO_CHARSET
|
||||
PROP_TO_CHARSET,
|
||||
PROP_USE_FALLBACK
|
||||
};
|
||||
|
||||
/**
|
||||
@ -63,6 +64,8 @@ struct _GCharsetConverter
|
||||
char *from;
|
||||
char *to;
|
||||
GIConv iconv;
|
||||
gboolean use_fallback;
|
||||
guint n_fallback_errors;
|
||||
};
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case PROP_USE_FALLBACK:
|
||||
conv->use_fallback = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -135,6 +142,10 @@ g_charset_converter_get_property (GObject *object,
|
||||
g_value_set_string (value, conv->from);
|
||||
break;
|
||||
|
||||
case PROP_USE_FALLBACK:
|
||||
g_value_set_boolean (value, conv->use_fallback);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -166,7 +177,15 @@ g_charset_converter_class_init (GCharsetConverterClass *klass)
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
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
|
||||
@ -215,6 +234,7 @@ g_charset_converter_reset (GConverter *converter)
|
||||
}
|
||||
|
||||
g_iconv (conv->iconv, NULL, NULL, NULL, NULL);
|
||||
conv->n_fallback_errors = 0;
|
||||
}
|
||||
|
||||
static GConverterResult
|
||||
@ -292,6 +312,27 @@ g_charset_converter_convert (GConverter *converter,
|
||||
|
||||
case EILSEQ:
|
||||
/* Invalid code sequence */
|
||||
if (conv->use_fallback)
|
||||
{
|
||||
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;
|
||||
@ -306,6 +347,7 @@ g_charset_converter_convert (GConverter *converter,
|
||||
}
|
||||
else
|
||||
{
|
||||
ok:
|
||||
ret = G_CONVERTER_CONVERTED;
|
||||
|
||||
if (in_left == 0 &&
|
||||
@ -319,6 +361,31 @@ g_charset_converter_convert (GConverter *converter,
|
||||
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
|
||||
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,
|
||||
const gchar *from_charset,
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user