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