/* * locales.c: Culture-sensitive handling * * Author: * Dick Porter (dick@ximian.com) * * (C) 2003 Ximian, Inc. */ #include #include #include #include #include #include #define DEBUG static void set_field_by_name (MonoObject *obj, const guchar *fieldname, gpointer value) { MonoClassField *field; field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); mono_field_set_value (obj, field, value); } static gpointer get_field_by_name (MonoObject *obj, const guchar *fieldname) { MonoClassField *field; gpointer ret; field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); mono_field_get_value (obj, field, &ret); return(ret); } #ifdef HAVE_ICU #include #include #include #include #include static MonoString *monostring_from_UChars (const UChar *res_str, UConverter *conv) { MonoString *str; UErrorCode ec; char *utf16_str; int32_t ret, utf16_strlen; utf16_strlen=u_strlen (res_str)*ucnv_getMaxCharSize (conv)+2; utf16_str=(char *)g_malloc0 (sizeof(char)*utf16_strlen); ec=U_ZERO_ERROR; ret=ucnv_fromUChars (conv, utf16_str, utf16_strlen, res_str, -1, &ec); if(ec==U_BUFFER_OVERFLOW_ERROR || ec==U_STRING_NOT_TERMINATED_WARNING) { /* This should never happen, cos we gave ourselves the * maximum length needed above */ g_assert_not_reached (); } str=mono_string_from_utf16 ((gunichar2 *)utf16_str); g_free (utf16_str); return(str); } static UChar *monostring_to_UChars (const MonoString *str, UConverter *conv) { UErrorCode ec; UChar *dest; int32_t ret, dest_strlen; /* Add 1 for the trailing NULL */ dest_strlen=mono_string_length (str)+1; dest=(UChar *)g_malloc0 (sizeof(UChar)*dest_strlen); ec=U_ZERO_ERROR; /* mono_string_length()*2 because its counting bytes not chars */ ret=ucnv_toUChars (conv, dest, dest_strlen, (const char *)mono_string_chars (str), mono_string_length (str)*2, &ec); if(ec==U_BUFFER_OVERFLOW_ERROR || ec==U_STRING_NOT_TERMINATED_WARNING) { /* This should never happen, cos we gave ourselves the * length needed above */ g_assert_not_reached (); } return(dest); } static MonoString *monostring_from_resource_index (const UResourceBundle *bundle, UConverter *conv, int32_t idx) { const UChar *res_str; int32_t res_strlen; UErrorCode ec; ec=U_ZERO_ERROR; res_str=ures_getStringByIndex (bundle, idx, &res_strlen, &ec); if(U_FAILURE (ec)) { return(NULL); } return(monostring_from_UChars (res_str, conv)); } static UResourceBundle *open_subbundle (const UResourceBundle *bundle, const char *name, int32_t req_count) { UResourceBundle *subbundle; UErrorCode ec; int32_t count; ec=U_ZERO_ERROR; subbundle=ures_getByKey (bundle, name, NULL, &ec); if(U_FAILURE (ec)) { /* Couldn't find the subbundle */ return(NULL); } count=ures_countArrayItems (bundle, name, &ec); if(U_FAILURE (ec)) { /* Couldn't count the subbundle */ ures_close (subbundle); return(NULL); } if(count!=req_count) { /* Bummer */ ures_close (subbundle); return(NULL); } return(subbundle); } static void set_array (MonoObject *obj, const guchar *fieldname, const UResourceBundle *bundle, const char *resname, int32_t req_count, UConverter *conv) { MonoArray *arr; UResourceBundle *subbundle; int i; subbundle=open_subbundle (bundle, resname, req_count); if(subbundle!=NULL) { arr=mono_array_new(mono_domain_get (), mono_defaults.string_class, req_count); for(i=0; i