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