|
1 /* |
|
2 * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
3 * |
|
4 * Copyright (c) 1999 |
|
5 * Silicon Graphics Computer Systems, Inc. |
|
6 * |
|
7 * Copyright (c) 1999 |
|
8 * Boris Fomitchev |
|
9 * |
|
10 * This material is provided "as is", with absolutely no warranty expressed |
|
11 * or implied. Any use is at your own risk. |
|
12 * |
|
13 * Permission to use or copy this software for any purpose is hereby granted |
|
14 * without fee, provided the above notices are retained on all copies. |
|
15 * Permission to modify the code and to distribute modified code is granted, |
|
16 * provided the above notices are retained, and a notice that the code was |
|
17 * modified is included with the above copyright notice. |
|
18 * |
|
19 */ |
|
20 |
|
21 // This file is #included into locale_impl.cpp, due to locale use many |
|
22 // statics from locale_impl.cpp |
|
23 |
|
24 #if defined(__SYMBIAN32__WSD__) |
|
25 # include "libstdcppwsd.h" |
|
26 |
|
27 void locale_index_lock_init() |
|
28 { |
|
29 get_locale_Index_lock()._M_lock.iState = _ENeedsNormalInit; |
|
30 get_locale_Index_lock()._M_lock.iPtr = NULL; |
|
31 get_locale_Index_lock()._M_lock.iReentry = 0; |
|
32 } |
|
33 # endif |
|
34 |
|
35 _STLP_BEGIN_NAMESPACE |
|
36 |
|
37 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) |
|
38 # define locale _STLP_NO_MEM_T_NAME(loc) |
|
39 #endif |
|
40 |
|
41 _STLP_DECLSPEC locale::facet::~facet() {} |
|
42 |
|
43 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES) |
|
44 // members that fail to be templates |
|
45 _STLP_DECLSPEC bool locale::operator()(const string& __x, |
|
46 const string& __y) const |
|
47 { return __locale_do_operator_call(*this, __x, __y); } |
|
48 |
|
49 # if !defined (_STLP_NO_WCHAR_T) |
|
50 _STLP_DECLSPEC bool locale::operator()(const wstring& __x, |
|
51 const wstring& __y) const |
|
52 { return __locale_do_operator_call(*this, __x, __y); } |
|
53 # endif |
|
54 #endif |
|
55 |
|
56 _STLP_DECLSPEC void _STLP_CALL locale::_M_throw_runtime_error(const char* name) { |
|
57 char buf[256]; |
|
58 |
|
59 if (name) { |
|
60 const char* prefix = "bad locale name: "; |
|
61 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) |
|
62 strcpy(buf, prefix); |
|
63 strncat(buf, name, _STLP_ARRAY_SIZE(buf) - strlen(prefix)); |
|
64 buf[_STLP_ARRAY_SIZE(buf) - 1] = 0; |
|
65 #else |
|
66 strcpy_s(_STLP_ARRAY_AND_SIZE(buf), prefix); |
|
67 strncat_s(_STLP_ARRAY_AND_SIZE(buf), name, _TRUNCATE); |
|
68 #endif |
|
69 } |
|
70 else { |
|
71 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) |
|
72 strcpy(buf, "locale error"); |
|
73 #else |
|
74 strcpy_s(_STLP_ARRAY_AND_SIZE(buf), "locale error"); |
|
75 #endif |
|
76 } |
|
77 _STLP_THROW(runtime_error(buf)); |
|
78 } |
|
79 |
|
80 |
|
81 // Takes a reference to a locale::id, and returns its numeric index. |
|
82 // If no numeric index has yet been assigned, assigns one. The return |
|
83 // value is always positive. |
|
84 static size_t _Stl_loc_get_index(locale::id& id) { |
|
85 if (id._M_index == 0) { |
|
86 #if defined (_STLP_ATOMIC_INCREMENT) && \ |
|
87 (!defined (_STLP_WIN32_VERSION) || (_STLP_WIN32_VERSION > 0x0400)) |
|
88 static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max); |
|
89 id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index); |
|
90 #else |
|
91 #if !defined(__SYMBIAN32__WSD__) |
|
92 static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER; |
|
93 #endif //__SYMBIAN32__WSD__ |
|
94 _STLP_auto_lock sentry(_Index_lock); |
|
95 size_t new_index = locale::id::_S_max++; |
|
96 id._M_index = new_index; |
|
97 #endif |
|
98 } |
|
99 return id._M_index; |
|
100 } |
|
101 |
|
102 // Default constructor: create a copy of the global locale. |
|
103 _STLP_DECLSPEC locale::locale() _STLP_NOTHROW |
|
104 : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl)) |
|
105 {} |
|
106 |
|
107 // Copy constructor |
|
108 _STLP_DECLSPEC locale::locale(const locale& L) _STLP_NOTHROW |
|
109 : _M_impl( _get_Locale_impl( L._M_impl ) ) |
|
110 {} |
|
111 |
|
112 _STLP_DECLSPEC void locale::_M_insert(facet* f, locale::id& n) { |
|
113 if (f) |
|
114 _M_impl->insert(f, _Stl_loc_get_index(n)); |
|
115 } |
|
116 |
|
117 locale::locale( _Locale_impl* impl ) : |
|
118 _M_impl( _get_Locale_impl( impl ) ) |
|
119 {} |
|
120 |
|
121 // Create a locale from a name. |
|
122 _STLP_DECLSPEC locale::locale(const char* name) |
|
123 : _M_impl(0) { |
|
124 if (!name) |
|
125 _M_throw_runtime_error(0); |
|
126 |
|
127 if (is_C_locale_name(name)) { |
|
128 _M_impl = _get_Locale_impl( locale::classic()._M_impl ); |
|
129 return; |
|
130 } |
|
131 |
|
132 _Locale_impl* impl = 0; |
|
133 _STLP_TRY { |
|
134 impl = new _Locale_impl(locale::id::_S_max, name); |
|
135 |
|
136 // Insert categories one at a time. |
|
137 _Locale_name_hint *hint = 0; |
|
138 hint = impl->insert_ctype_facets(name, hint); |
|
139 hint = impl->insert_numeric_facets(name, hint); |
|
140 hint = impl->insert_time_facets(name, hint); |
|
141 hint = impl->insert_collate_facets(name, hint); |
|
142 hint = impl->insert_monetary_facets(name, hint); |
|
143 impl->insert_messages_facets(name, hint); |
|
144 // reassign impl |
|
145 _M_impl = _get_Locale_impl( impl ); |
|
146 } |
|
147 _STLP_UNWIND(delete impl); |
|
148 } |
|
149 |
|
150 // Give L a name where all facets except those in category c |
|
151 // are taken from name1, and those in category c are taken from name2. |
|
152 static void _Stl_loc_combine_names(_Locale_impl* L, |
|
153 const char* name1, const char* name2, |
|
154 locale::category c) { |
|
155 if ((c & locale::all) == 0 || strcmp(name1, name2) == 0) |
|
156 L->name = name1; |
|
157 else if ((c & locale::all) == locale::all) |
|
158 L->name = name2; |
|
159 else { |
|
160 // Decompose the names. |
|
161 char ctype_buf[_Locale_MAX_SIMPLE_NAME]; |
|
162 char numeric_buf[_Locale_MAX_SIMPLE_NAME]; |
|
163 char time_buf[_Locale_MAX_SIMPLE_NAME]; |
|
164 char collate_buf[_Locale_MAX_SIMPLE_NAME]; |
|
165 char monetary_buf[_Locale_MAX_SIMPLE_NAME]; |
|
166 char messages_buf[_Locale_MAX_SIMPLE_NAME]; |
|
167 |
|
168 // TODO: check returnvalues? |
|
169 _Locale_extract_ctype_name((c & locale::ctype) ? name2 : name1, ctype_buf, 0); |
|
170 _Locale_extract_numeric_name((c & locale::numeric) ? name2 : name1, numeric_buf, 0); |
|
171 _Locale_extract_time_name((c & locale::time) ? name2 : name1, time_buf, 0); |
|
172 _Locale_extract_collate_name((c & locale::collate) ? name2 : name1, collate_buf, 0); |
|
173 _Locale_extract_monetary_name((c & locale::monetary) ? name2 : name1, monetary_buf, 0); |
|
174 _Locale_extract_messages_name((c & locale::messages) ? name2 : name1, messages_buf, 0); |
|
175 |
|
176 // Construct a new composite name. |
|
177 char composite_buf[_Locale_MAX_COMPOSITE_NAME]; |
|
178 // TODO: check returnvalue? |
|
179 _Locale_compose_name(composite_buf, |
|
180 ctype_buf, numeric_buf, time_buf, |
|
181 collate_buf, monetary_buf, messages_buf, |
|
182 name1); |
|
183 L->name = composite_buf; |
|
184 } |
|
185 } |
|
186 |
|
187 // Create a locale that's a copy of L, except that all of the facets |
|
188 // in category c are instead constructed by name. |
|
189 _STLP_DECLSPEC locale::locale(const locale& L, const char* name, locale::category c) |
|
190 : _M_impl(0) { |
|
191 if (name == 0 || (_Nameless == name)) |
|
192 _M_throw_runtime_error(name); |
|
193 |
|
194 _Locale_impl* impl = 0; |
|
195 |
|
196 _STLP_TRY { |
|
197 impl = new _Locale_impl(*L._M_impl); |
|
198 _Stl_loc_combine_names(impl, L._M_impl->name.c_str(), name, c); |
|
199 |
|
200 _Locale_name_hint *hint = 0; |
|
201 if (c & locale::ctype) |
|
202 hint = impl->insert_ctype_facets(name, hint); |
|
203 if (c & locale::numeric) |
|
204 hint = impl->insert_numeric_facets(name, hint); |
|
205 if (c & locale::time) |
|
206 hint = impl->insert_time_facets(name, hint); |
|
207 if (c & locale::collate) |
|
208 hint = impl->insert_collate_facets(name, hint); |
|
209 if (c & locale::monetary) |
|
210 hint = impl->insert_monetary_facets(name, hint); |
|
211 if (c & locale::messages) |
|
212 impl->insert_messages_facets(name, hint); |
|
213 _M_impl = _get_Locale_impl( impl ); |
|
214 } |
|
215 _STLP_UNWIND(delete impl) |
|
216 } |
|
217 #if defined(__SYMBIAN32__WSD__) |
|
218 #define id GetFacetLocaleId() |
|
219 #endif |
|
220 // Contruct a new locale where all facets that aren't in category c |
|
221 // come from L1, and all those that are in category c come from L2. |
|
222 _STLP_DECLSPEC locale::locale(const locale& L1, const locale& L2, category c) |
|
223 : _M_impl(0) { |
|
224 _Locale_impl* impl = new _Locale_impl(*L1._M_impl); |
|
225 |
|
226 _Locale_impl* i2 = L2._M_impl; |
|
227 |
|
228 if (L1.name() != _Nameless && L2.name() != _Nameless) |
|
229 _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c); |
|
230 else { |
|
231 impl->name = _Nameless; |
|
232 } |
|
233 |
|
234 if (c & collate) { |
|
235 impl->insert( i2, _STLP_STD::collate<char>::id); |
|
236 # ifndef _STLP_NO_WCHAR_T |
|
237 impl->insert( i2, _STLP_STD::collate<wchar_t>::id); |
|
238 # endif |
|
239 } |
|
240 if (c & ctype) { |
|
241 impl->insert( i2, _STLP_STD::ctype<char>::id); |
|
242 impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id); |
|
243 # ifndef _STLP_NO_WCHAR_T |
|
244 impl->insert( i2, _STLP_STD::ctype<wchar_t>::id); |
|
245 impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id); |
|
246 # endif |
|
247 } |
|
248 if (c & monetary) { |
|
249 impl->insert( i2, _STLP_STD::moneypunct<char, true>::id); |
|
250 impl->insert( i2, _STLP_STD::moneypunct<char, false>::id); |
|
251 impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id); |
|
252 impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); |
|
253 # ifndef _STLP_NO_WCHAR_T |
|
254 impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id); |
|
255 impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id); |
|
256 impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
|
257 impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
|
258 # endif |
|
259 } |
|
260 if (c & numeric) { |
|
261 impl->insert( i2, _STLP_STD::numpunct<char>::id); |
|
262 impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id); |
|
263 impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); |
|
264 # ifndef _STLP_NO_WCHAR_T |
|
265 impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id); |
|
266 impl->insert( i2, num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
|
267 impl->insert( i2, num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
|
268 # endif |
|
269 } |
|
270 if (c & time) { |
|
271 impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id); |
|
272 impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); |
|
273 # ifndef _STLP_NO_WCHAR_T |
|
274 impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
|
275 impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
|
276 # endif |
|
277 } |
|
278 if (c & messages) { |
|
279 impl->insert( i2, _STLP_STD::messages<char>::id); |
|
280 # ifndef _STLP_NO_WCHAR_T |
|
281 impl->insert( i2, _STLP_STD::messages<wchar_t>::id); |
|
282 # endif |
|
283 } |
|
284 #if defined(__SYMBIAN32__WSD__) |
|
285 #undef id |
|
286 #endif |
|
287 _M_impl = _get_Locale_impl( impl ); |
|
288 } |
|
289 |
|
290 // Destructor. |
|
291 _STLP_DECLSPEC locale::~locale() _STLP_NOTHROW { |
|
292 if (_M_impl) |
|
293 _release_Locale_impl(_M_impl); |
|
294 } |
|
295 |
|
296 // Assignment operator. Much like the copy constructor: just a bit of |
|
297 // pointer twiddling. |
|
298 _STLP_DECLSPEC const locale& locale::operator=(const locale& L) _STLP_NOTHROW { |
|
299 if (this->_M_impl != L._M_impl) { |
|
300 if (this->_M_impl) |
|
301 _release_Locale_impl(this->_M_impl); |
|
302 this->_M_impl = _get_Locale_impl(L._M_impl); |
|
303 } |
|
304 return *this; |
|
305 } |
|
306 |
|
307 _STLP_DECLSPEC locale::facet* locale::_M_get_facet(const locale::id& n) const { |
|
308 return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0; |
|
309 } |
|
310 |
|
311 _STLP_DECLSPEC locale::facet* locale::_M_use_facet(const locale::id& n) const { |
|
312 locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0); |
|
313 if (!f) |
|
314 _M_impl->_M_throw_bad_cast(); |
|
315 return f; |
|
316 } |
|
317 |
|
318 _STLP_DECLSPEC string locale::name() const { |
|
319 return _M_impl->name; |
|
320 } |
|
321 |
|
322 // Compare two locales for equality. |
|
323 _STLP_DECLSPEC bool locale::operator==(const locale& L) const { |
|
324 return this->_M_impl == L._M_impl || |
|
325 (this->name() == L.name() && this->name() != _Nameless); |
|
326 } |
|
327 |
|
328 _STLP_DECLSPEC bool locale::operator!=(const locale& L) const { |
|
329 return !(*this == L); |
|
330 } |
|
331 |
|
332 // static data members. |
|
333 |
|
334 _STLP_DECLSPEC const locale& _STLP_CALL locale::classic() { |
|
335 return *_Stl_get_classic_locale(); |
|
336 } |
|
337 |
|
338 _STLP_DECLSPEC locale _STLP_CALL locale::global(const locale& L) { |
|
339 locale old(_Stl_get_global_locale()->_M_impl); |
|
340 if (_Stl_get_global_locale()->_M_impl != L._M_impl) { |
|
341 _release_Locale_impl(_Stl_get_global_locale()->_M_impl); |
|
342 // this assign should be atomic, should be fixed here: |
|
343 _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl); |
|
344 |
|
345 // Set the global C locale, if appropriate. |
|
346 #if !defined(_STLP_NO_LOCALE_SUPPORT) |
|
347 if (L.name() != _Nameless) |
|
348 setlocale(LC_ALL, L.name().c_str()); |
|
349 #endif |
|
350 } |
|
351 |
|
352 return old; |
|
353 } |
|
354 |
|
355 # if !defined (_STLP_STATIC_CONST_INIT_BUG) && ! defined (_STLP_USE_DECLSPEC) |
|
356 |
|
357 const locale::category locale::none; |
|
358 const locale::category locale::collate; |
|
359 const locale::category locale::ctype; |
|
360 const locale::category locale::monetary; |
|
361 const locale::category locale::numeric; |
|
362 const locale::category locale::time; |
|
363 const locale::category locale::messages; |
|
364 const locale::category locale::all; |
|
365 |
|
366 # endif |
|
367 |
|
368 _STLP_END_NAMESPACE |
|
369 |