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
15U_NAMESPACE_USE
16
17
18namespace BPrivate {
19namespace Libroot {
20
21
22ICUNumericData::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
34void
35ICUNumericData::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
44status_t
45ICUNumericData::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
98status_t
99ICUNumericData::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
117const char*
118ICUNumericData::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