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