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