sl@0: /* sl@0: * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: * sl@0: * Copyright (c) 1999 sl@0: * Silicon Graphics Computer Systems, Inc. sl@0: * sl@0: * Copyright (c) 1999 sl@0: * Boris Fomitchev sl@0: * sl@0: * This material is provided "as is", with absolutely no warranty expressed sl@0: * or implied. Any use is at your own risk. sl@0: * sl@0: * Permission to use or copy this software for any purpose is hereby granted sl@0: * without fee, provided the above notices are retained on all copies. sl@0: * Permission to modify the code and to distribute modified code is granted, sl@0: * provided the above notices are retained, and a notice that the code was sl@0: * modified is included with the above copyright notice. sl@0: * sl@0: */ sl@0: sl@0: // This file is #included into locale_impl.cpp, due to locale use many sl@0: // statics from locale_impl.cpp sl@0: sl@0: #if defined(__SYMBIAN32__WSD__) sl@0: # include "libstdcppwsd.h" sl@0: sl@0: void locale_index_lock_init() sl@0: { sl@0: get_locale_Index_lock()._M_lock.iState = _ENeedsNormalInit; sl@0: get_locale_Index_lock()._M_lock.iPtr = NULL; sl@0: get_locale_Index_lock()._M_lock.iReentry = 0; sl@0: } sl@0: # endif sl@0: sl@0: _STLP_BEGIN_NAMESPACE sl@0: sl@0: #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) sl@0: # define locale _STLP_NO_MEM_T_NAME(loc) sl@0: #endif sl@0: sl@0: _STLP_DECLSPEC locale::facet::~facet() {} sl@0: sl@0: #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES) sl@0: // members that fail to be templates sl@0: _STLP_DECLSPEC bool locale::operator()(const string& __x, sl@0: const string& __y) const sl@0: { return __locale_do_operator_call(*this, __x, __y); } sl@0: sl@0: # if !defined (_STLP_NO_WCHAR_T) sl@0: _STLP_DECLSPEC bool locale::operator()(const wstring& __x, sl@0: const wstring& __y) const sl@0: { return __locale_do_operator_call(*this, __x, __y); } sl@0: # endif sl@0: #endif sl@0: sl@0: _STLP_DECLSPEC void _STLP_CALL locale::_M_throw_runtime_error(const char* name) { sl@0: char buf[256]; sl@0: sl@0: if (name) { sl@0: const char* prefix = "bad locale name: "; sl@0: #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) sl@0: strcpy(buf, prefix); sl@0: strncat(buf, name, _STLP_ARRAY_SIZE(buf) - strlen(prefix)); sl@0: buf[_STLP_ARRAY_SIZE(buf) - 1] = 0; sl@0: #else sl@0: strcpy_s(_STLP_ARRAY_AND_SIZE(buf), prefix); sl@0: strncat_s(_STLP_ARRAY_AND_SIZE(buf), name, _TRUNCATE); sl@0: #endif sl@0: } sl@0: else { sl@0: #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) sl@0: strcpy(buf, "locale error"); sl@0: #else sl@0: strcpy_s(_STLP_ARRAY_AND_SIZE(buf), "locale error"); sl@0: #endif sl@0: } sl@0: _STLP_THROW(runtime_error(buf)); sl@0: } sl@0: sl@0: sl@0: // Takes a reference to a locale::id, and returns its numeric index. sl@0: // If no numeric index has yet been assigned, assigns one. The return sl@0: // value is always positive. sl@0: static size_t _Stl_loc_get_index(locale::id& id) { sl@0: if (id._M_index == 0) { sl@0: #if defined (_STLP_ATOMIC_INCREMENT) && \ sl@0: (!defined (_STLP_WIN32_VERSION) || (_STLP_WIN32_VERSION > 0x0400)) sl@0: static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max); sl@0: id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index); sl@0: #else sl@0: #if !defined(__SYMBIAN32__WSD__) sl@0: static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER; sl@0: #endif //__SYMBIAN32__WSD__ sl@0: _STLP_auto_lock sentry(_Index_lock); sl@0: size_t new_index = locale::id::_S_max++; sl@0: id._M_index = new_index; sl@0: #endif sl@0: } sl@0: return id._M_index; sl@0: } sl@0: sl@0: // Default constructor: create a copy of the global locale. sl@0: _STLP_DECLSPEC locale::locale() _STLP_NOTHROW sl@0: : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl)) sl@0: {} sl@0: sl@0: // Copy constructor sl@0: _STLP_DECLSPEC locale::locale(const locale& L) _STLP_NOTHROW sl@0: : _M_impl( _get_Locale_impl( L._M_impl ) ) sl@0: {} sl@0: sl@0: _STLP_DECLSPEC void locale::_M_insert(facet* f, locale::id& n) { sl@0: if (f) sl@0: _M_impl->insert(f, _Stl_loc_get_index(n)); sl@0: } sl@0: sl@0: locale::locale( _Locale_impl* impl ) : sl@0: _M_impl( _get_Locale_impl( impl ) ) sl@0: {} sl@0: sl@0: // Create a locale from a name. sl@0: _STLP_DECLSPEC locale::locale(const char* name) sl@0: : _M_impl(0) { sl@0: if (!name) sl@0: _M_throw_runtime_error(0); sl@0: sl@0: if (is_C_locale_name(name)) { sl@0: _M_impl = _get_Locale_impl( locale::classic()._M_impl ); sl@0: return; sl@0: } sl@0: sl@0: _Locale_impl* impl = 0; sl@0: _STLP_TRY { sl@0: impl = new _Locale_impl(locale::id::_S_max, name); sl@0: sl@0: // Insert categories one at a time. sl@0: _Locale_name_hint *hint = 0; sl@0: hint = impl->insert_ctype_facets(name, hint); sl@0: hint = impl->insert_numeric_facets(name, hint); sl@0: hint = impl->insert_time_facets(name, hint); sl@0: hint = impl->insert_collate_facets(name, hint); sl@0: hint = impl->insert_monetary_facets(name, hint); sl@0: impl->insert_messages_facets(name, hint); sl@0: // reassign impl sl@0: _M_impl = _get_Locale_impl( impl ); sl@0: } sl@0: _STLP_UNWIND(delete impl); sl@0: } sl@0: sl@0: // Give L a name where all facets except those in category c sl@0: // are taken from name1, and those in category c are taken from name2. sl@0: static void _Stl_loc_combine_names(_Locale_impl* L, sl@0: const char* name1, const char* name2, sl@0: locale::category c) { sl@0: if ((c & locale::all) == 0 || strcmp(name1, name2) == 0) sl@0: L->name = name1; sl@0: else if ((c & locale::all) == locale::all) sl@0: L->name = name2; sl@0: else { sl@0: // Decompose the names. sl@0: char ctype_buf[_Locale_MAX_SIMPLE_NAME]; sl@0: char numeric_buf[_Locale_MAX_SIMPLE_NAME]; sl@0: char time_buf[_Locale_MAX_SIMPLE_NAME]; sl@0: char collate_buf[_Locale_MAX_SIMPLE_NAME]; sl@0: char monetary_buf[_Locale_MAX_SIMPLE_NAME]; sl@0: char messages_buf[_Locale_MAX_SIMPLE_NAME]; sl@0: sl@0: // TODO: check returnvalues? sl@0: _Locale_extract_ctype_name((c & locale::ctype) ? name2 : name1, ctype_buf, 0); sl@0: _Locale_extract_numeric_name((c & locale::numeric) ? name2 : name1, numeric_buf, 0); sl@0: _Locale_extract_time_name((c & locale::time) ? name2 : name1, time_buf, 0); sl@0: _Locale_extract_collate_name((c & locale::collate) ? name2 : name1, collate_buf, 0); sl@0: _Locale_extract_monetary_name((c & locale::monetary) ? name2 : name1, monetary_buf, 0); sl@0: _Locale_extract_messages_name((c & locale::messages) ? name2 : name1, messages_buf, 0); sl@0: sl@0: // Construct a new composite name. sl@0: char composite_buf[_Locale_MAX_COMPOSITE_NAME]; sl@0: // TODO: check returnvalue? sl@0: _Locale_compose_name(composite_buf, sl@0: ctype_buf, numeric_buf, time_buf, sl@0: collate_buf, monetary_buf, messages_buf, sl@0: name1); sl@0: L->name = composite_buf; sl@0: } sl@0: } sl@0: sl@0: // Create a locale that's a copy of L, except that all of the facets sl@0: // in category c are instead constructed by name. sl@0: _STLP_DECLSPEC locale::locale(const locale& L, const char* name, locale::category c) sl@0: : _M_impl(0) { sl@0: if (name == 0 || (_Nameless == name)) sl@0: _M_throw_runtime_error(name); sl@0: sl@0: _Locale_impl* impl = 0; sl@0: sl@0: _STLP_TRY { sl@0: impl = new _Locale_impl(*L._M_impl); sl@0: _Stl_loc_combine_names(impl, L._M_impl->name.c_str(), name, c); sl@0: sl@0: _Locale_name_hint *hint = 0; sl@0: if (c & locale::ctype) sl@0: hint = impl->insert_ctype_facets(name, hint); sl@0: if (c & locale::numeric) sl@0: hint = impl->insert_numeric_facets(name, hint); sl@0: if (c & locale::time) sl@0: hint = impl->insert_time_facets(name, hint); sl@0: if (c & locale::collate) sl@0: hint = impl->insert_collate_facets(name, hint); sl@0: if (c & locale::monetary) sl@0: hint = impl->insert_monetary_facets(name, hint); sl@0: if (c & locale::messages) sl@0: impl->insert_messages_facets(name, hint); sl@0: _M_impl = _get_Locale_impl( impl ); sl@0: } sl@0: _STLP_UNWIND(delete impl) sl@0: } sl@0: #if defined(__SYMBIAN32__WSD__) sl@0: #define id GetFacetLocaleId() sl@0: #endif sl@0: // Contruct a new locale where all facets that aren't in category c sl@0: // come from L1, and all those that are in category c come from L2. sl@0: _STLP_DECLSPEC locale::locale(const locale& L1, const locale& L2, category c) sl@0: : _M_impl(0) { sl@0: _Locale_impl* impl = new _Locale_impl(*L1._M_impl); sl@0: sl@0: _Locale_impl* i2 = L2._M_impl; sl@0: sl@0: if (L1.name() != _Nameless && L2.name() != _Nameless) sl@0: _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c); sl@0: else { sl@0: impl->name = _Nameless; sl@0: } sl@0: sl@0: if (c & collate) { sl@0: impl->insert( i2, _STLP_STD::collate::id); sl@0: # ifndef _STLP_NO_WCHAR_T sl@0: impl->insert( i2, _STLP_STD::collate::id); sl@0: # endif sl@0: } sl@0: if (c & ctype) { sl@0: impl->insert( i2, _STLP_STD::ctype::id); sl@0: impl->insert( i2, _STLP_STD::codecvt::id); sl@0: # ifndef _STLP_NO_WCHAR_T sl@0: impl->insert( i2, _STLP_STD::ctype::id); sl@0: impl->insert( i2, _STLP_STD::codecvt::id); sl@0: # endif sl@0: } sl@0: if (c & monetary) { sl@0: impl->insert( i2, _STLP_STD::moneypunct::id); sl@0: impl->insert( i2, _STLP_STD::moneypunct::id); sl@0: impl->insert( i2, _STLP_STD::money_get > >::id); sl@0: impl->insert( i2, _STLP_STD::money_put > >::id); sl@0: # ifndef _STLP_NO_WCHAR_T sl@0: impl->insert( i2, _STLP_STD::moneypunct::id); sl@0: impl->insert( i2, _STLP_STD::moneypunct::id); sl@0: impl->insert( i2, _STLP_STD::money_get > >::id); sl@0: impl->insert( i2, _STLP_STD::money_put > >::id); sl@0: # endif sl@0: } sl@0: if (c & numeric) { sl@0: impl->insert( i2, _STLP_STD::numpunct::id); sl@0: impl->insert( i2, _STLP_STD::num_get > >::id); sl@0: impl->insert( i2, _STLP_STD::num_put > >::id); sl@0: # ifndef _STLP_NO_WCHAR_T sl@0: impl->insert( i2, _STLP_STD::numpunct::id); sl@0: impl->insert( i2, num_get > >::id); sl@0: impl->insert( i2, num_put > >::id); sl@0: # endif sl@0: } sl@0: if (c & time) { sl@0: impl->insert( i2, _STLP_STD::time_get > >::id); sl@0: impl->insert( i2, _STLP_STD::time_put > >::id); sl@0: # ifndef _STLP_NO_WCHAR_T sl@0: impl->insert( i2, _STLP_STD::time_get > >::id); sl@0: impl->insert( i2, _STLP_STD::time_put > >::id); sl@0: # endif sl@0: } sl@0: if (c & messages) { sl@0: impl->insert( i2, _STLP_STD::messages::id); sl@0: # ifndef _STLP_NO_WCHAR_T sl@0: impl->insert( i2, _STLP_STD::messages::id); sl@0: # endif sl@0: } sl@0: #if defined(__SYMBIAN32__WSD__) sl@0: #undef id sl@0: #endif sl@0: _M_impl = _get_Locale_impl( impl ); sl@0: } sl@0: sl@0: // Destructor. sl@0: _STLP_DECLSPEC locale::~locale() _STLP_NOTHROW { sl@0: if (_M_impl) sl@0: _release_Locale_impl(_M_impl); sl@0: } sl@0: sl@0: // Assignment operator. Much like the copy constructor: just a bit of sl@0: // pointer twiddling. sl@0: _STLP_DECLSPEC const locale& locale::operator=(const locale& L) _STLP_NOTHROW { sl@0: if (this->_M_impl != L._M_impl) { sl@0: if (this->_M_impl) sl@0: _release_Locale_impl(this->_M_impl); sl@0: this->_M_impl = _get_Locale_impl(L._M_impl); sl@0: } sl@0: return *this; sl@0: } sl@0: sl@0: _STLP_DECLSPEC locale::facet* locale::_M_get_facet(const locale::id& n) const { sl@0: return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0; sl@0: } sl@0: sl@0: _STLP_DECLSPEC locale::facet* locale::_M_use_facet(const locale::id& n) const { sl@0: locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0); sl@0: if (!f) sl@0: _M_impl->_M_throw_bad_cast(); sl@0: return f; sl@0: } sl@0: sl@0: _STLP_DECLSPEC string locale::name() const { sl@0: return _M_impl->name; sl@0: } sl@0: sl@0: // Compare two locales for equality. sl@0: _STLP_DECLSPEC bool locale::operator==(const locale& L) const { sl@0: return this->_M_impl == L._M_impl || sl@0: (this->name() == L.name() && this->name() != _Nameless); sl@0: } sl@0: sl@0: _STLP_DECLSPEC bool locale::operator!=(const locale& L) const { sl@0: return !(*this == L); sl@0: } sl@0: sl@0: // static data members. sl@0: sl@0: _STLP_DECLSPEC const locale& _STLP_CALL locale::classic() { sl@0: return *_Stl_get_classic_locale(); sl@0: } sl@0: sl@0: _STLP_DECLSPEC locale _STLP_CALL locale::global(const locale& L) { sl@0: locale old(_Stl_get_global_locale()->_M_impl); sl@0: if (_Stl_get_global_locale()->_M_impl != L._M_impl) { sl@0: _release_Locale_impl(_Stl_get_global_locale()->_M_impl); sl@0: // this assign should be atomic, should be fixed here: sl@0: _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl); sl@0: sl@0: // Set the global C locale, if appropriate. sl@0: #if !defined(_STLP_NO_LOCALE_SUPPORT) sl@0: if (L.name() != _Nameless) sl@0: setlocale(LC_ALL, L.name().c_str()); sl@0: #endif sl@0: } sl@0: sl@0: return old; sl@0: } sl@0: sl@0: # if !defined (_STLP_STATIC_CONST_INIT_BUG) && ! defined (_STLP_USE_DECLSPEC) sl@0: sl@0: const locale::category locale::none; sl@0: const locale::category locale::collate; sl@0: const locale::category locale::ctype; sl@0: const locale::category locale::monetary; sl@0: const locale::category locale::numeric; sl@0: const locale::category locale::time; sl@0: const locale::category locale::messages; sl@0: const locale::category locale::all; sl@0: sl@0: # endif sl@0: sl@0: _STLP_END_NAMESPACE sl@0: