xref: /haiku/src/kits/locale/Country.cpp (revision 5c4b63b505326ac530e26f1926b511949888c5c9)
1 /*
2  * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2009-2010, Adrien Destugues, pulkomandy@gmail.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include <Country.h>
9 
10 #include <AutoDeleter.h>
11 #include <IconUtils.h>
12 #include <List.h>
13 #include <Resources.h>
14 #include <String.h>
15 #include <TimeZone.h>
16 
17 #include <unicode/datefmt.h>
18 #include <unicode/locid.h>
19 #include <unicode/ulocdata.h>
20 #include <ICUWrapper.h>
21 
22 #include <iostream>
23 #include <map>
24 #include <monetary.h>
25 #include <new>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 
29 
30 #define ICU_VERSION icu_44
31 
32 
33 BCountry::BCountry(const char* languageCode, const char* countryCode)
34 	:
35 	fICULocale(new ICU_VERSION::Locale(languageCode, countryCode))
36 {
37 }
38 
39 
40 BCountry::BCountry(const char* languageAndCountryCode)
41 	:
42 	fICULocale(new ICU_VERSION::Locale(languageAndCountryCode))
43 {
44 }
45 
46 
47 BCountry::BCountry(const BCountry& other)
48 	:
49 	fICULocale(new ICU_VERSION::Locale(*other.fICULocale))
50 {
51 }
52 
53 
54 BCountry&
55 BCountry::operator=(const BCountry& other)
56 {
57 	if (this == &other)
58 		return *this;
59 
60 	*fICULocale = *other.fICULocale;
61 
62 	return *this;
63 }
64 
65 
66 BCountry::~BCountry()
67 {
68 	delete fICULocale;
69 }
70 
71 
72 bool
73 BCountry::GetName(BString& name) const
74 {
75 	UnicodeString uString;
76 	fICULocale->getDisplayCountry(uString);
77 	BStringByteSink stringConverter(&name);
78 	uString.toUTF8(stringConverter);
79 	return true;
80 }
81 
82 
83 const char*
84 BCountry::Code() const
85 {
86 	return fICULocale->getName();
87 }
88 
89 
90 status_t
91 BCountry::GetIcon(BBitmap* result) const
92 {
93 	if (result == NULL)
94 		return B_BAD_DATA;
95 	// TODO: a proper way to locate the library being used ?
96 	BResources storage("/boot/system/lib/liblocale.so");
97 	if (storage.InitCheck() != B_OK)
98 		return B_ERROR;
99 	size_t size;
100 	const char* code = fICULocale->getCountry();
101 	if (code != NULL) {
102 		const void* buffer = storage.LoadResource(B_VECTOR_ICON_TYPE, code,
103 			&size);
104 		if (buffer != NULL && size != 0) {
105 			return BIconUtils::GetVectorIcon(static_cast<const uint8*>(buffer),
106 				size, result);
107 		}
108 	}
109 	return B_BAD_DATA;
110 }
111 
112 
113 // TODO does ICU even support this ? Is it in the keywords ?
114 int8
115 BCountry::Measurement() const
116 {
117 	UErrorCode error = U_ZERO_ERROR;
118 	switch (ulocdata_getMeasurementSystem(Code(), &error)) {
119 		case UMS_US:
120 			return B_US;
121 		case UMS_SI:
122 		default:
123 			return B_METRIC;
124 	}
125 }
126 
127 
128 // #pragma mark - Timezones
129 
130 
131 int
132 BCountry::GetTimeZones(BList& timezones) const
133 {
134 	ObjectDeleter<StringEnumeration> icuTimeZoneList
135 		= TimeZone::createEnumeration(fICULocale->getCountry());
136 	if (icuTimeZoneList.Get() == NULL)
137 		return 0;
138 
139 	UErrorCode error = U_ZERO_ERROR;
140 
141 	const char* tzName;
142 	std::map<BString, BTimeZone*> timeZoneMap;
143 		// The map allows us to remove duplicates and get a count of the
144 		// remaining zones after that
145 	while ((tzName = icuTimeZoneList->next(NULL, error)) != NULL) {
146 		if (error == U_ZERO_ERROR) {
147 			BTimeZone* timeZone = new(std::nothrow) BTimeZone(tzName);
148 			timeZoneMap.insert(std::pair<BString, BTimeZone*>(timeZone->Name(),
149 				timeZone));
150 		} else
151 			error = U_ZERO_ERROR;
152 	}
153 
154 	std::map<BString, BTimeZone*>::const_iterator tzIter;
155 	for (tzIter = timeZoneMap.begin(); tzIter != timeZoneMap.end(); ++tzIter)
156 		timezones.AddItem(tzIter->second);
157 
158 	return timezones.CountItems();
159 }
160 
161 
162