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