xref: /haiku/src/system/libroot/add-ons/icu/ICUNumericData.cpp (revision 0d452c8f34013b611a54c746a71c05e28796eae2)
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 namespace Libroot {
16 
17 
18 ICUNumericData::ICUNumericData(struct lconv& localeConv)
19 	:
20 	fLocaleConv(localeConv),
21 	fDataBridge(NULL)
22 {
23 	fLocaleConv.decimal_point = fDecimalPoint;
24 	fLocaleConv.thousands_sep = fThousandsSep;
25 	fLocaleConv.grouping = fGrouping;
26 }
27 
28 
29 void
30 ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge)
31 {
32 	dataBridge->glibcNumericLocale.values[0].string = fDecimalPoint;
33 	dataBridge->glibcNumericLocale.values[1].string = fThousandsSep;
34 	dataBridge->glibcNumericLocale.values[2].string = fGrouping;
35 	fDataBridge = dataBridge;
36 }
37 
38 
39 status_t
40 ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName)
41 {
42 	status_t result = inherited::SetTo(locale, posixLocaleName);
43 
44 	if (result == B_OK) {
45 		UErrorCode icuStatus = U_ZERO_ERROR;
46 		DecimalFormat* numberFormat = dynamic_cast<DecimalFormat*>(
47 			NumberFormat::createInstance(locale, UNUM_DECIMAL, 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->glibcNumericLocale.values[3].word
61 				= (unsigned int)fDecimalPoint[0];
62 		}
63 		if (result == B_OK) {
64 			result = _SetLocaleconvEntry(formatSymbols, fThousandsSep,
65 				DecimalFormatSymbols::kGroupingSeparatorSymbol);
66 			fDataBridge->glibcNumericLocale.values[4].word
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->glibcNumericLocale.values[3].word
103 			= (unsigned int)fDecimalPoint[0];
104 		fDataBridge->glibcNumericLocale.values[4].word
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 Libroot
127 }	// namespace BPrivate
128