1 /* 2 * Copyright 2010-2011, Oliver Tappe, zooey@hirschkaefer.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "ICUNumericData.h" 8 9 #include <langinfo.h> 10 #include <locale.h> 11 #include <strings.h> 12 13 14 namespace BPrivate { 15 namespace Libroot { 16 17 18 ICUNumericData::ICUNumericData(pthread_key_t tlsKey, struct lconv& localeConv) 19 : 20 inherited(tlsKey), 21 fLocaleConv(localeConv), 22 fDataBridge(NULL) 23 { 24 fLocaleConv.decimal_point = fDecimalPoint; 25 fLocaleConv.thousands_sep = fThousandsSep; 26 fLocaleConv.grouping = fGrouping; 27 } 28 29 30 void 31 ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge) 32 { 33 dataBridge->glibcNumericLocale.values[0].string = fDecimalPoint; 34 dataBridge->glibcNumericLocale.values[1].string = fThousandsSep; 35 dataBridge->glibcNumericLocale.values[2].string = fGrouping; 36 fDataBridge = dataBridge; 37 } 38 39 40 status_t 41 ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName) 42 { 43 status_t result = inherited::SetTo(locale, posixLocaleName); 44 45 if (result == B_OK) { 46 UErrorCode icuStatus = U_ZERO_ERROR; 47 DecimalFormat* numberFormat = dynamic_cast<DecimalFormat*>( 48 NumberFormat::createInstance(locale, UNUM_DECIMAL, icuStatus)); 49 if (!U_SUCCESS(icuStatus)) 50 return B_UNSUPPORTED; 51 if (!numberFormat) 52 return B_BAD_TYPE; 53 const DecimalFormatSymbols* formatSymbols 54 = numberFormat->getDecimalFormatSymbols(); 55 if (!formatSymbols) 56 result = B_BAD_DATA; 57 58 if (result == B_OK) { 59 result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint, 60 DecimalFormatSymbols::kDecimalSeparatorSymbol); 61 fDataBridge->glibcNumericLocale.values[3].word 62 = (unsigned int)fDecimalPoint[0]; 63 } 64 if (result == B_OK) { 65 result = _SetLocaleconvEntry(formatSymbols, fThousandsSep, 66 DecimalFormatSymbols::kGroupingSeparatorSymbol); 67 fDataBridge->glibcNumericLocale.values[4].word 68 = (unsigned int)fThousandsSep[0]; 69 } 70 if (result == B_OK) { 71 int32 groupingSize = numberFormat->getGroupingSize(); 72 if (groupingSize < 1) 73 fGrouping[0] = '\0'; 74 else { 75 fGrouping[0] = groupingSize; 76 int32 secondaryGroupingSize 77 = numberFormat->getSecondaryGroupingSize(); 78 if (secondaryGroupingSize < 1) 79 fGrouping[1] = '\0'; 80 else { 81 fGrouping[1] = secondaryGroupingSize; 82 fGrouping[2] = '\0'; 83 } 84 } 85 } 86 87 delete numberFormat; 88 } 89 90 return result; 91 } 92 93 94 status_t 95 ICUNumericData::SetToPosix() 96 { 97 status_t result = inherited::SetToPosix(); 98 99 if (result == B_OK) { 100 strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point); 101 strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep); 102 strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping); 103 fDataBridge->glibcNumericLocale.values[3].word 104 = (unsigned int)fDecimalPoint[0]; 105 fDataBridge->glibcNumericLocale.values[4].word 106 = (unsigned int)fThousandsSep[0]; 107 } 108 109 return result; 110 } 111 112 113 const char* 114 ICUNumericData::GetLanginfo(int index) 115 { 116 switch(index) { 117 case RADIXCHAR: 118 return fDecimalPoint; 119 case THOUSEP: 120 return fThousandsSep; 121 default: 122 return ""; 123 } 124 } 125 126 127 } // namespace Libroot 128 } // namespace BPrivate 129