X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Flocales.c;h=9316b410cd6fcc1d13b13de6ca147141bdc9e98b;hb=c1086268ba833338bd33ea268f453ebcc063c7bd;hp=23b75cbae97d834ff195ecb3c963d48c98ce7bc5;hpb=4ef4438ad9e8cb0f79b9e472b38dbd0cd848d812;p=mono.git diff --git a/mono/metadata/locales.c b/mono/metadata/locales.c index 23b75cbae97..9316b410cd6 100644 --- a/mono/metadata/locales.c +++ b/mono/metadata/locales.c @@ -10,6 +10,7 @@ * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * (C) 2003 PT Cakram Datalingga Duaribu http://www.cdl2000.com * Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -91,11 +92,13 @@ region_name_locator (const void *a, const void *b) } static MonoArray* -create_group_sizes_array (const gint *gs, gint ml) +create_group_sizes_array (const gint *gs, gint ml, MonoError *error) { MonoArray *ret; int i, len = 0; + mono_error_init (error); + for (i = 0; i < ml; i++) { if (gs [i] == -1) break; @@ -103,7 +106,8 @@ create_group_sizes_array (const gint *gs, gint ml) } ret = mono_array_new_cached (mono_domain_get (), - mono_get_int32_class (), len); + mono_get_int32_class (), len, error); + return_val_if_nok (error, NULL); for(i = 0; i < len; i++) mono_array_set (ret, gint32, i, gs [i]); @@ -112,32 +116,37 @@ create_group_sizes_array (const gint *gs, gint ml) } static MonoArray* -create_names_array_idx (const guint16 *names, int ml) +create_names_array_idx (const guint16 *names, int ml, MonoError *error) { MonoArray *ret; MonoDomain *domain; int i; + mono_error_init (error); + if (names == NULL) return NULL; domain = mono_domain_get (); - ret = mono_array_new_cached (mono_domain_get (), mono_get_string_class (), ml); + ret = mono_array_new_cached (mono_domain_get (), mono_get_string_class (), ml, error); + return_val_if_nok (error, NULL); for(i = 0; i < ml; i++) - mono_array_setref (ret, i, mono_string_new (domain, idx2string (names [i]))); + mono_array_setref (ret, i, mono_string_new (domain, dtidx2string (names [i]))); return ret; } static MonoArray* -create_names_array_idx_dynamic (const guint16 *names, int ml) +create_names_array_idx_dynamic (const guint16 *names, int ml, MonoError *error) { MonoArray *ret; MonoDomain *domain; int i, len = 0; + mono_error_init (error); + if (names == NULL) return NULL; @@ -149,10 +158,11 @@ create_names_array_idx_dynamic (const guint16 *names, int ml) len++; } - ret = mono_array_new_cached (mono_domain_get (), mono_get_string_class (), len); + ret = mono_array_new_cached (mono_domain_get (), mono_get_string_class (), len, error); + return_val_if_nok (error, NULL); for(i = 0; i < len; i++) - mono_array_setref (ret, i, mono_string_new (domain, idx2string (names [i]))); + mono_array_setref (ret, i, mono_string_new (domain, pattern2string (names [i]))); return ret; } @@ -160,13 +170,16 @@ create_names_array_idx_dynamic (const guint16 *names, int ml) MonoBoolean ves_icall_System_Globalization_CalendarData_fill_calendar_data (MonoCalendarData *this_obj, MonoString *name, gint32 calendar_index) { + MonoError error; MonoDomain *domain; const DateTimeFormatEntry *dfe; const CultureInfoNameEntry *ne; const CultureInfoEntry *ci; char *n; - n = mono_string_to_utf8 (name); + n = mono_string_to_utf8_checked (name, &error); + if (mono_error_set_pending_exception (&error)) + return FALSE; ne = (const CultureInfoNameEntry *)mono_binary_search (n, culture_name_entries, NUM_CULTURE_ENTRIES, sizeof (CultureInfoNameEntry), culture_name_locator); g_free (n); @@ -180,24 +193,52 @@ ves_icall_System_Globalization_CalendarData_fill_calendar_data (MonoCalendarData domain = mono_domain_get (); MONO_OBJECT_SETREF (this_obj, NativeName, mono_string_new (domain, idx2string (ci->nativename))); - MONO_OBJECT_SETREF (this_obj, ShortDatePatterns, create_names_array_idx_dynamic (dfe->short_date_patterns, - NUM_SHORT_DATE_PATTERNS)); - MONO_OBJECT_SETREF (this_obj, YearMonthPatterns, create_names_array_idx_dynamic (dfe->year_month_patterns, - NUM_YEAR_MONTH_PATTERNS)); - - MONO_OBJECT_SETREF (this_obj, LongDatePatterns, create_names_array_idx_dynamic (dfe->long_date_patterns, - NUM_LONG_DATE_PATTERNS)); - MONO_OBJECT_SETREF (this_obj, MonthDayPattern, mono_string_new (domain, idx2string (dfe->month_day_pattern))); - - MONO_OBJECT_SETREF (this_obj, DayNames, create_names_array_idx (dfe->day_names, NUM_DAYS)); - MONO_OBJECT_SETREF (this_obj, AbbreviatedDayNames, create_names_array_idx (dfe->abbreviated_day_names, - NUM_DAYS)); - MONO_OBJECT_SETREF (this_obj, SuperShortDayNames, create_names_array_idx (dfe->shortest_day_names, NUM_DAYS)); - MONO_OBJECT_SETREF (this_obj, MonthNames, create_names_array_idx (dfe->month_names, NUM_MONTHS)); - MONO_OBJECT_SETREF (this_obj, AbbreviatedMonthNames, create_names_array_idx (dfe->abbreviated_month_names, - NUM_MONTHS)); - MONO_OBJECT_SETREF (this_obj, GenitiveMonthNames, create_names_array_idx (dfe->month_genitive_names, NUM_MONTHS)); - MONO_OBJECT_SETREF (this_obj, GenitiveAbbreviatedMonthNames, create_names_array_idx (dfe->abbreviated_month_genitive_names, NUM_MONTHS)); + MonoArray *short_date_patterns = create_names_array_idx_dynamic (dfe->short_date_patterns, + NUM_SHORT_DATE_PATTERNS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, ShortDatePatterns, short_date_patterns); + MonoArray *year_month_patterns =create_names_array_idx_dynamic (dfe->year_month_patterns, + NUM_YEAR_MONTH_PATTERNS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, YearMonthPatterns, year_month_patterns); + + MonoArray *long_date_patterns = create_names_array_idx_dynamic (dfe->long_date_patterns, + NUM_LONG_DATE_PATTERNS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, LongDatePatterns, long_date_patterns); + + MONO_OBJECT_SETREF (this_obj, MonthDayPattern, mono_string_new (domain, pattern2string (dfe->month_day_pattern))); + + MonoArray *day_names = create_names_array_idx (dfe->day_names, NUM_DAYS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, DayNames, day_names); + + MonoArray *abbr_day_names = create_names_array_idx (dfe->abbreviated_day_names, + NUM_DAYS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, AbbreviatedDayNames, abbr_day_names); + + MonoArray *ss_day_names = create_names_array_idx (dfe->shortest_day_names, NUM_DAYS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, SuperShortDayNames, ss_day_names); + + MonoArray *month_names = create_names_array_idx (dfe->month_names, NUM_MONTHS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, MonthNames, month_names); + + MonoArray *abbr_mon_names = create_names_array_idx (dfe->abbreviated_month_names, + NUM_MONTHS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, AbbreviatedMonthNames, abbr_mon_names); + + + MonoArray *gen_month_names = create_names_array_idx (dfe->month_genitive_names, NUM_MONTHS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, GenitiveMonthNames, gen_month_names); + + MonoArray *gen_abbr_mon_names = create_names_array_idx (dfe->abbreviated_month_genitive_names, NUM_MONTHS, &error); + return_val_and_set_pending_if_nok (&error, FALSE); + MONO_OBJECT_SETREF (this_obj, GenitiveAbbreviatedMonthNames, gen_abbr_mon_names); return TRUE; } @@ -205,6 +246,7 @@ ves_icall_System_Globalization_CalendarData_fill_calendar_data (MonoCalendarData void ves_icall_System_Globalization_CultureData_fill_culture_data (MonoCultureData *this_obj, gint32 datetime_index) { + MonoError error; MonoDomain *domain; const DateTimeFormatEntry *dfe; @@ -217,10 +259,18 @@ ves_icall_System_Globalization_CultureData_fill_culture_data (MonoCultureData *t MONO_OBJECT_SETREF (this_obj, AMDesignator, mono_string_new (domain, idx2string (dfe->am_designator))); MONO_OBJECT_SETREF (this_obj, PMDesignator, mono_string_new (domain, idx2string (dfe->pm_designator))); MONO_OBJECT_SETREF (this_obj, TimeSeparator, mono_string_new (domain, idx2string (dfe->time_separator))); - MONO_OBJECT_SETREF (this_obj, LongTimePatterns, create_names_array_idx_dynamic (dfe->long_time_patterns, - NUM_LONG_TIME_PATTERNS)); - MONO_OBJECT_SETREF (this_obj, ShortTimePatterns, create_names_array_idx_dynamic (dfe->short_time_patterns, - NUM_SHORT_TIME_PATTERNS)); + + MonoArray *long_time_patterns = create_names_array_idx_dynamic (dfe->long_time_patterns, + NUM_LONG_TIME_PATTERNS, &error); + if (mono_error_set_pending_exception (&error)) + return; + MONO_OBJECT_SETREF (this_obj, LongTimePatterns, long_time_patterns); + + MonoArray *short_time_patterns = create_names_array_idx_dynamic (dfe->short_time_patterns, + NUM_SHORT_TIME_PATTERNS, &error); + if (mono_error_set_pending_exception (&error)) + return; + MONO_OBJECT_SETREF (this_obj, ShortTimePatterns, short_time_patterns); this_obj->FirstDayOfWeek = dfe->first_day_of_week; this_obj->CalendarWeekRule = dfe->calendar_week_rule; } @@ -228,6 +278,7 @@ ves_icall_System_Globalization_CultureData_fill_culture_data (MonoCultureData *t void ves_icall_System_Globalization_CultureData_fill_number_data (MonoNumberFormatInfo* number, gint32 number_index) { + MonoError error; MonoDomain *domain; const NumberFormatEntry *nfe; @@ -242,8 +293,11 @@ ves_icall_System_Globalization_CultureData_fill_number_data (MonoNumberFormatInf idx2string (nfe->currency_decimal_separator))); MONO_OBJECT_SETREF (number, currencyGroupSeparator, mono_string_new (domain, idx2string (nfe->currency_group_separator))); - MONO_OBJECT_SETREF (number, currencyGroupSizes, create_group_sizes_array (nfe->currency_group_sizes, - GROUP_SIZE)); + MonoArray *currency_sizes_arr = create_group_sizes_array (nfe->currency_group_sizes, + GROUP_SIZE, &error); + if (mono_error_set_pending_exception (&error)) + return; + MONO_OBJECT_SETREF (number, currencyGroupSizes, currency_sizes_arr); number->currencyNegativePattern = nfe->currency_negative_pattern; number->currencyPositivePattern = nfe->currency_positive_pattern; MONO_OBJECT_SETREF (number, currencySymbol, mono_string_new (domain, idx2string (nfe->currency_symbol))); @@ -255,8 +309,11 @@ ves_icall_System_Globalization_CultureData_fill_number_data (MonoNumberFormatInf MONO_OBJECT_SETREF (number, numberDecimalSeparator, mono_string_new (domain, idx2string (nfe->number_decimal_separator))); MONO_OBJECT_SETREF (number, numberGroupSeparator, mono_string_new (domain, idx2string (nfe->number_group_separator))); - MONO_OBJECT_SETREF (number, numberGroupSizes, create_group_sizes_array (nfe->number_group_sizes, - GROUP_SIZE)); + MonoArray *number_sizes_arr = create_group_sizes_array (nfe->number_group_sizes, + GROUP_SIZE, &error); + if (mono_error_set_pending_exception (&error)) + return; + MONO_OBJECT_SETREF (number, numberGroupSizes, number_sizes_arr); number->numberNegativePattern = nfe->number_negative_pattern; number->percentNegativePattern = nfe->percent_negative_pattern; number->percentPositivePattern = nfe->percent_positive_pattern; @@ -268,10 +325,12 @@ ves_icall_System_Globalization_CultureData_fill_number_data (MonoNumberFormatInf } static MonoBoolean -construct_culture (MonoCultureInfo *this_obj, const CultureInfoEntry *ci) +construct_culture (MonoCultureInfo *this_obj, const CultureInfoEntry *ci, MonoError *error) { MonoDomain *domain = mono_domain_get (); + mono_error_init (error); + this_obj->lcid = ci->lcid; MONO_OBJECT_SETREF (this_obj, name, mono_string_new (domain, idx2string (ci->name))); MONO_OBJECT_SETREF (this_obj, englishname, mono_string_new (domain, idx2string (ci->englishname))); @@ -283,7 +342,10 @@ construct_culture (MonoCultureInfo *this_obj, const CultureInfoEntry *ci) // It's null for neutral cultures if (ci->territory > 0) MONO_OBJECT_SETREF (this_obj, territory, mono_string_new (domain, idx2string (ci->territory))); - MONO_OBJECT_SETREF (this_obj, native_calendar_names, create_names_array_idx (ci->native_calendar_names, NUM_CALENDARS)); + + MonoArray *native_calendar_names = create_names_array_idx (ci->native_calendar_names, NUM_CALENDARS, error); + return_val_if_nok (error, FALSE); + MONO_OBJECT_SETREF (this_obj, native_calendar_names, native_calendar_names); this_obj->parent_lcid = ci->parent_lcid; this_obj->datetime_index = ci->datetime_format_index; this_obj->number_index = ci->number_format_index; @@ -372,7 +434,7 @@ get_darwin_locale (void) len += bytes_converted + 1; } - darwin_locale = (char *) malloc (len + 1); + darwin_locale = (char *) g_malloc (len + 1); CFStringGetBytes (locale_language, CFRangeMake (0, CFStringGetLength (locale_language)), kCFStringEncodingMacRoman, 0, FALSE, (UInt8 *) darwin_locale, len, &bytes_converted); darwin_locale[bytes_converted] = '-'; @@ -392,9 +454,9 @@ get_darwin_locale (void) if (locale_cfstr) { len = CFStringGetMaximumSizeForEncoding (CFStringGetLength (locale_cfstr), kCFStringEncodingMacRoman) + 1; - darwin_locale = (char *) malloc (len); + darwin_locale = (char *) g_malloc (len); if (!CFStringGetCString (locale_cfstr, darwin_locale, len, kCFStringEncodingMacRoman)) { - free (darwin_locale); + g_free (darwin_locale); CFRelease (locale); darwin_locale = NULL; return NULL; @@ -492,23 +554,31 @@ MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid (MonoCultureInfo *this_obj, gint lcid) { + MonoError error; const CultureInfoEntry *ci; ci = culture_info_entry_from_lcid (lcid); if(ci == NULL) return FALSE; - return construct_culture (this_obj, ci); + if (!construct_culture (this_obj, ci, &error)) { + mono_error_set_pending_exception (&error); + return FALSE; + } + return TRUE; } MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name (MonoCultureInfo *this_obj, MonoString *name) { + MonoError error; const CultureInfoNameEntry *ne; char *n; - n = mono_string_to_utf8 (name); + n = mono_string_to_utf8_checked (name, &error); + if (mono_error_set_pending_exception (&error)) + return FALSE; ne = (const CultureInfoNameEntry *)mono_binary_search (n, culture_name_entries, NUM_CULTURE_ENTRIES, sizeof (CultureInfoNameEntry), culture_name_locator); @@ -519,7 +589,11 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name ( } g_free (n); - return construct_culture (this_obj, &culture_entries [ne->culture_entry_index]); + if (!construct_culture (this_obj, &culture_entries [ne->culture_entry_index], &error)) { + mono_error_set_pending_exception (&error); + return FALSE; + } + return TRUE; } /* MonoBoolean @@ -553,10 +627,13 @@ MonoBoolean ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_name (MonoRegionInfo *this_obj, MonoString *name) { + MonoError error; const RegionInfoNameEntry *ne; char *n; - n = mono_string_to_utf8 (name); + n = mono_string_to_utf8_checked (name, &error); + if (mono_error_set_pending_exception (&error)) + return FALSE; ne = (const RegionInfoNameEntry *)mono_binary_search (n, region_name_entries, NUM_REGION_ENTRIES, sizeof (RegionInfoNameEntry), region_name_locator); @@ -600,7 +677,9 @@ ves_icall_System_Globalization_CultureInfo_internal_get_cultures (MonoBoolean ne if (neutral) len++; - ret = mono_array_new (domain, klass, len); + ret = mono_array_new_checked (domain, klass, len, &error); + if (!is_ok (&error)) + goto fail; if (len == 0) return ret; @@ -614,15 +693,21 @@ ves_icall_System_Globalization_CultureInfo_internal_get_cultures (MonoBoolean ne is_neutral = ci->territory == 0; if ((neutral && is_neutral) || (specific && !is_neutral)) { culture = (MonoCultureInfo *) mono_object_new_checked (domain, klass, &error); - mono_error_raise_exception (&error); - mono_runtime_object_init ((MonoObject *) culture); - construct_culture (culture, ci); + if (!is_ok (&error)) goto fail; + mono_runtime_object_init_checked ((MonoObject *) culture, &error); + if (!is_ok (&error)) goto fail; + if (!construct_culture (culture, ci, &error)) + goto fail; culture->use_user_override = TRUE; mono_array_setref (ret, len++, culture); } } return ret; + +fail: + mono_error_set_pending_exception (&error); + return ret; } int ves_icall_System_Globalization_CompareInfo_internal_compare (MonoCompareInfo *this_obj, MonoString *str1, gint32 off1, gint32 len1, MonoString *str2, gint32 off2, gint32 len2, gint32 options) @@ -636,13 +721,17 @@ int ves_icall_System_Globalization_CompareInfo_internal_compare (MonoCompareInfo void ves_icall_System_Globalization_CompareInfo_assign_sortkey (MonoCompareInfo *this_obj, MonoSortKey *key, MonoString *source, gint32 options) { + MonoError error; MonoArray *arr; gint32 keylen, i; keylen=mono_string_length (source); - arr=mono_array_new (mono_domain_get (), mono_get_byte_class (), - keylen); + arr=mono_array_new_checked (mono_domain_get (), mono_get_byte_class (), + keylen, &error); + if (mono_error_set_pending_exception (&error)) + return; + for(i=0; i