xref: /haiku/src/system/libroot/add-ons/icu/ICUNumericData.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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