diff --git a/headers/private/libroot/locale/LocaleBackend.h b/headers/private/libroot/locale/LocaleBackend.h index 1393a6b959..3c19319948 100644 --- a/headers/private/libroot/locale/LocaleBackend.h +++ b/headers/private/libroot/locale/LocaleBackend.h @@ -14,6 +14,7 @@ struct lconv; struct lc_time_t; +struct locale_data; // glibc namespace BPrivate { @@ -47,14 +48,33 @@ struct LocaleMonetaryDataBridge { struct LocaleNumericDataBridge { - const char** addrOfGlibcDecimalPoint; - const char** addrOfGlibcThousandsSep; - const char** addrOfGlibcGrouping; - uint32_t* addrOfGlibcWCDecimalPoint; - uint32_t* addrOfGlibcWCThousandsSep; +private: + // struct used by glibc to store numeric locale data + struct GlibcNumericLocale { + const char* name; + const char* filedata; + off_t filesize; + int mmaped; + unsigned int usage_count; + int use_translit; + const char *options; + unsigned int nstrings; + union locale_data_value + { + const uint32_t* wstr; + const char* string; + unsigned int word; + } + values[6]; + }; + locale_data* originalGlibcLocale; + +public: const struct lconv* posixLocaleConv; + GlibcNumericLocale glibcNumericLocale; LocaleNumericDataBridge(); + ~LocaleNumericDataBridge(); }; diff --git a/src/system/libroot/add-ons/icu/ICUNumericData.cpp b/src/system/libroot/add-ons/icu/ICUNumericData.cpp index 6a410ee46e..b59aa64df9 100644 --- a/src/system/libroot/add-ons/icu/ICUNumericData.cpp +++ b/src/system/libroot/add-ons/icu/ICUNumericData.cpp @@ -28,9 +28,9 @@ ICUNumericData::ICUNumericData(struct lconv& localeConv) void ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge) { - *dataBridge->addrOfGlibcDecimalPoint = fDecimalPoint; - *dataBridge->addrOfGlibcThousandsSep = fThousandsSep; - *dataBridge->addrOfGlibcGrouping = fGrouping; + dataBridge->glibcNumericLocale.values[0].string = fDecimalPoint; + dataBridge->glibcNumericLocale.values[1].string = fThousandsSep; + dataBridge->glibcNumericLocale.values[2].string = fGrouping; fDataBridge = dataBridge; } @@ -57,13 +57,13 @@ ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName) if (result == B_OK) { result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint, DecimalFormatSymbols::kDecimalSeparatorSymbol); - *fDataBridge->addrOfGlibcWCDecimalPoint + fDataBridge->glibcNumericLocale.values[3].word = (unsigned int)fDecimalPoint[0]; } if (result == B_OK) { result = _SetLocaleconvEntry(formatSymbols, fThousandsSep, DecimalFormatSymbols::kGroupingSeparatorSymbol); - *fDataBridge->addrOfGlibcWCThousandsSep + fDataBridge->glibcNumericLocale.values[4].word = (unsigned int)fThousandsSep[0]; } if (result == B_OK) { @@ -99,9 +99,9 @@ ICUNumericData::SetToPosix() strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point); strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep); strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping); - *fDataBridge->addrOfGlibcWCDecimalPoint + fDataBridge->glibcNumericLocale.values[3].word = (unsigned int)fDecimalPoint[0]; - *fDataBridge->addrOfGlibcWCThousandsSep + fDataBridge->glibcNumericLocale.values[4].word = (unsigned int)fThousandsSep[0]; } diff --git a/src/system/libroot/posix/locale/LocaleDataBridge.cpp b/src/system/libroot/posix/locale/LocaleDataBridge.cpp index 57b3a3ed8a..1b9817d552 100644 --- a/src/system/libroot/posix/locale/LocaleDataBridge.cpp +++ b/src/system/libroot/posix/locale/LocaleDataBridge.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -16,26 +17,7 @@ #include -// struct used by glibc to access locale info -struct locale_data -{ - const char* name; - const char* filedata; - off_t filesize; - int mmaped; - unsigned int usage_count; - int use_translit; - const char *options; - unsigned int nstrings; - union locale_data_value - { - const uint32_t* wstr; - const char* string; - unsigned int word; - } - values[]; -}; -extern struct locale_data _nl_C_LC_NUMERIC; +extern locale_data* _nl_current_LC_NUMERIC; namespace BPrivate { @@ -69,13 +51,18 @@ LocaleMonetaryDataBridge::LocaleMonetaryDataBridge() LocaleNumericDataBridge::LocaleNumericDataBridge() : - addrOfGlibcDecimalPoint(&_nl_C_LC_NUMERIC.values[0].string), - addrOfGlibcThousandsSep(&_nl_C_LC_NUMERIC.values[1].string), - addrOfGlibcGrouping(&_nl_C_LC_NUMERIC.values[2].string), - addrOfGlibcWCDecimalPoint(&_nl_C_LC_NUMERIC.values[3].word), - addrOfGlibcWCThousandsSep(&_nl_C_LC_NUMERIC.values[4].word), + originalGlibcLocale(_nl_current_LC_NUMERIC), posixLocaleConv(&gPosixLocaleConv) { + memcpy(&glibcNumericLocale, _nl_current_LC_NUMERIC, + sizeof(glibcNumericLocale)); + _nl_current_LC_NUMERIC = (locale_data*)&glibcNumericLocale; +} + + +LocaleNumericDataBridge::~LocaleNumericDataBridge() +{ + _nl_current_LC_NUMERIC = originalGlibcLocale; }