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