xref: /haiku/src/system/libroot/add-ons/icu/ICUNumericData.cpp (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
1560b10ffSOliver Tappe /*
2c894d186SOliver Tappe  * Copyright 2010-2011, Oliver Tappe, zooey@hirschkaefer.de.
3560b10ffSOliver Tappe  * Distributed under the terms of the MIT License.
4560b10ffSOliver Tappe  */
5560b10ffSOliver Tappe 
6560b10ffSOliver Tappe 
7560b10ffSOliver Tappe #include "ICUNumericData.h"
8560b10ffSOliver Tappe 
9560b10ffSOliver Tappe #include <langinfo.h>
10560b10ffSOliver Tappe #include <locale.h>
113aeed660SJérôme Duval #include <string.h>
12560b10ffSOliver Tappe #include <strings.h>
13560b10ffSOliver Tappe 
14560b10ffSOliver Tappe 
151bad1ff3SAdrien Destugues U_NAMESPACE_USE
161bad1ff3SAdrien Destugues 
171bad1ff3SAdrien Destugues 
18560b10ffSOliver Tappe namespace BPrivate {
1925dc253dSIngo Weinhold namespace Libroot {
20560b10ffSOliver Tappe 
21560b10ffSOliver Tappe 
ICUNumericData(pthread_key_t tlsKey,struct lconv & localeConv)22bf5ff480SOliver Tappe ICUNumericData::ICUNumericData(pthread_key_t tlsKey, struct lconv& localeConv)
23560b10ffSOliver Tappe 	:
24bf5ff480SOliver Tappe 	inherited(tlsKey),
25560b10ffSOliver Tappe 	fLocaleConv(localeConv),
26560b10ffSOliver Tappe 	fDataBridge(NULL)
27560b10ffSOliver Tappe {
28560b10ffSOliver Tappe 	fLocaleConv.decimal_point = fDecimalPoint;
29560b10ffSOliver Tappe 	fLocaleConv.thousands_sep = fThousandsSep;
30560b10ffSOliver Tappe 	fLocaleConv.grouping = fGrouping;
31560b10ffSOliver Tappe }
32560b10ffSOliver Tappe 
33560b10ffSOliver Tappe 
34560b10ffSOliver Tappe void
Initialize(LocaleNumericDataBridge * dataBridge)35560b10ffSOliver Tappe ICUNumericData::Initialize(LocaleNumericDataBridge* dataBridge)
36560b10ffSOliver Tappe {
37*d338200eSTrung Nguyen 	dataBridge->glibcNumericLocale->values[0].string = fDecimalPoint;
38*d338200eSTrung Nguyen 	dataBridge->glibcNumericLocale->values[1].string = fThousandsSep;
39*d338200eSTrung Nguyen 	dataBridge->glibcNumericLocale->values[2].string = fGrouping;
40560b10ffSOliver Tappe 	fDataBridge = dataBridge;
41560b10ffSOliver Tappe }
42560b10ffSOliver Tappe 
43560b10ffSOliver Tappe 
44560b10ffSOliver Tappe status_t
SetTo(const Locale & locale,const char * posixLocaleName)45560b10ffSOliver Tappe ICUNumericData::SetTo(const Locale& locale, const char* posixLocaleName)
46560b10ffSOliver Tappe {
47560b10ffSOliver Tappe 	status_t result = inherited::SetTo(locale, posixLocaleName);
48560b10ffSOliver Tappe 
49560b10ffSOliver Tappe 	if (result == B_OK) {
50560b10ffSOliver Tappe 		UErrorCode icuStatus = U_ZERO_ERROR;
51560b10ffSOliver Tappe 		DecimalFormat* numberFormat = dynamic_cast<DecimalFormat*>(
5245f2f22bSOliver Tappe 			NumberFormat::createInstance(locale, UNUM_DECIMAL, icuStatus));
53560b10ffSOliver Tappe 		if (!U_SUCCESS(icuStatus))
54560b10ffSOliver Tappe 			return B_UNSUPPORTED;
55560b10ffSOliver Tappe 		if (!numberFormat)
56560b10ffSOliver Tappe 			return B_BAD_TYPE;
57560b10ffSOliver Tappe 		const DecimalFormatSymbols* formatSymbols
58560b10ffSOliver Tappe 			= numberFormat->getDecimalFormatSymbols();
59560b10ffSOliver Tappe 		if (!formatSymbols)
60560b10ffSOliver Tappe 			result = B_BAD_DATA;
61560b10ffSOliver Tappe 
62560b10ffSOliver Tappe 		if (result == B_OK) {
63560b10ffSOliver Tappe 			result = _SetLocaleconvEntry(formatSymbols, fDecimalPoint,
64560b10ffSOliver Tappe 				DecimalFormatSymbols::kDecimalSeparatorSymbol);
65*d338200eSTrung Nguyen 			fDataBridge->glibcNumericLocale->values[3].word
66560b10ffSOliver Tappe 				= (unsigned int)fDecimalPoint[0];
67560b10ffSOliver Tappe 		}
68560b10ffSOliver Tappe 		if (result == B_OK) {
69560b10ffSOliver Tappe 			result = _SetLocaleconvEntry(formatSymbols, fThousandsSep,
70560b10ffSOliver Tappe 				DecimalFormatSymbols::kGroupingSeparatorSymbol);
71*d338200eSTrung Nguyen 			fDataBridge->glibcNumericLocale->values[4].word
72560b10ffSOliver Tappe 				= (unsigned int)fThousandsSep[0];
73560b10ffSOliver Tappe 		}
74560b10ffSOliver Tappe 		if (result == B_OK) {
75560b10ffSOliver Tappe 			int32 groupingSize = numberFormat->getGroupingSize();
76560b10ffSOliver Tappe 			if (groupingSize < 1)
77560b10ffSOliver Tappe 				fGrouping[0] = '\0';
78560b10ffSOliver Tappe 			else {
79560b10ffSOliver Tappe 				fGrouping[0] = groupingSize;
80560b10ffSOliver Tappe 				int32 secondaryGroupingSize
81560b10ffSOliver Tappe 					= numberFormat->getSecondaryGroupingSize();
82560b10ffSOliver Tappe 				if (secondaryGroupingSize < 1)
83560b10ffSOliver Tappe 					fGrouping[1] = '\0';
84560b10ffSOliver Tappe 				else {
85560b10ffSOliver Tappe 					fGrouping[1] = secondaryGroupingSize;
86560b10ffSOliver Tappe 					fGrouping[2] = '\0';
87560b10ffSOliver Tappe 				}
88560b10ffSOliver Tappe 			}
89560b10ffSOliver Tappe 		}
90560b10ffSOliver Tappe 
91560b10ffSOliver Tappe 		delete numberFormat;
92560b10ffSOliver Tappe 	}
93560b10ffSOliver Tappe 
94560b10ffSOliver Tappe 	return result;
95560b10ffSOliver Tappe }
96560b10ffSOliver Tappe 
97560b10ffSOliver Tappe 
98560b10ffSOliver Tappe status_t
SetToPosix()99560b10ffSOliver Tappe ICUNumericData::SetToPosix()
100560b10ffSOliver Tappe {
101560b10ffSOliver Tappe 	status_t result = inherited::SetToPosix();
102560b10ffSOliver Tappe 
103560b10ffSOliver Tappe 	if (result == B_OK) {
104560b10ffSOliver Tappe 		strcpy(fDecimalPoint, fDataBridge->posixLocaleConv->decimal_point);
105560b10ffSOliver Tappe 		strcpy(fThousandsSep, fDataBridge->posixLocaleConv->thousands_sep);
106560b10ffSOliver Tappe 		strcpy(fGrouping, fDataBridge->posixLocaleConv->grouping);
107*d338200eSTrung Nguyen 		fDataBridge->glibcNumericLocale->values[3].word
108560b10ffSOliver Tappe 			= (unsigned int)fDecimalPoint[0];
109*d338200eSTrung Nguyen 		fDataBridge->glibcNumericLocale->values[4].word
110560b10ffSOliver Tappe 			= (unsigned int)fThousandsSep[0];
111560b10ffSOliver Tappe 	}
112560b10ffSOliver Tappe 
113560b10ffSOliver Tappe 	return result;
114560b10ffSOliver Tappe }
115560b10ffSOliver Tappe 
116560b10ffSOliver Tappe 
117560b10ffSOliver Tappe const char*
GetLanginfo(int index)118560b10ffSOliver Tappe ICUNumericData::GetLanginfo(int index)
119560b10ffSOliver Tappe {
120560b10ffSOliver Tappe 	switch(index) {
121560b10ffSOliver Tappe 		case RADIXCHAR:
122560b10ffSOliver Tappe 			return fDecimalPoint;
123560b10ffSOliver Tappe 		case THOUSEP:
124560b10ffSOliver Tappe 			return fThousandsSep;
125560b10ffSOliver Tappe 		default:
126560b10ffSOliver Tappe 			return "";
127560b10ffSOliver Tappe 	}
128560b10ffSOliver Tappe }
129560b10ffSOliver Tappe 
130560b10ffSOliver Tappe 
13125dc253dSIngo Weinhold }	// namespace Libroot
132560b10ffSOliver Tappe }	// namespace BPrivate
133