/home/ntakagi/work/STLport-5.1.5/src/locale.cppGo to the documentation of this file.00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 // This file is #included into locale_impl.cpp, due to locale use many 00020 // statics from locale_impl.cpp 00021 00022 _STLP_BEGIN_NAMESPACE 00023 00024 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00025 # define locale _STLP_NO_MEM_T_NAME(loc) 00026 #endif 00027 00028 locale::facet::~facet() {} 00029 00030 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES) 00031 // members that fail to be templates 00032 bool locale::operator()(const string& __x, 00033 const string& __y) const 00034 { return __locale_do_operator_call(*this, __x, __y); } 00035 00036 # if !defined (_STLP_NO_WCHAR_T) 00037 bool locale::operator()(const wstring& __x, 00038 const wstring& __y) const 00039 { return __locale_do_operator_call(*this, __x, __y); } 00040 # endif 00041 #endif 00042 00043 void _STLP_CALL locale::_M_throw_runtime_error(const char* name) { 00044 char buf[256]; 00045 00046 if (name) { 00047 const char* prefix = "bad locale name: "; 00048 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00049 strcpy(buf, prefix); 00050 strncat(buf, name, _STLP_ARRAY_SIZE(buf) - strlen(prefix)); 00051 buf[_STLP_ARRAY_SIZE(buf) - 1] = 0; 00052 #else 00053 strcpy_s(_STLP_ARRAY_AND_SIZE(buf), prefix); 00054 strncat_s(_STLP_ARRAY_AND_SIZE(buf), name, _TRUNCATE); 00055 #endif 00056 } 00057 else { 00058 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00059 strcpy(buf, "locale error"); 00060 #else 00061 strcpy_s(_STLP_ARRAY_AND_SIZE(buf), "locale error"); 00062 #endif 00063 } 00064 _STLP_THROW(runtime_error(buf)); 00065 } 00066 00067 // Takes a reference to a locale::id, and returns its numeric index. 00068 // If no numeric index has yet been assigned, assigns one. The return 00069 // value is always positive. 00070 static size_t _Stl_loc_get_index(locale::id& id) { 00071 if (id._M_index == 0) { 00072 #if defined (_STLP_ATOMIC_INCREMENT) && \ 00073 (!defined (_STLP_WIN32_VERSION) || (_STLP_WIN32_VERSION > 0x0400)) 00074 static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max); 00075 id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index); 00076 #else 00077 static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER; 00078 _STLP_auto_lock sentry(_Index_lock); 00079 size_t new_index = locale::id::_S_max++; 00080 id._M_index = new_index; 00081 #endif 00082 } 00083 return id._M_index; 00084 } 00085 00086 // Default constructor: create a copy of the global locale. 00087 locale::locale() _STLP_NOTHROW 00088 : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl)) 00089 {} 00090 00091 // Copy constructor 00092 locale::locale(const locale& L) _STLP_NOTHROW 00093 : _M_impl( _get_Locale_impl( L._M_impl ) ) 00094 {} 00095 00096 void locale::_M_insert(facet* f, locale::id& n) { 00097 if (f) 00098 _M_impl->insert(f, _Stl_loc_get_index(n)); 00099 } 00100 00101 locale::locale( _Locale_impl* impl ) : 00102 _M_impl( _get_Locale_impl( impl ) ) 00103 {} 00104 00105 // Create a locale from a name. 00106 locale::locale(const char* name) 00107 : _M_impl(0) { 00108 if (!name) 00109 _M_throw_runtime_error(0); 00110 00111 if (is_C_locale_name(name)) { 00112 _M_impl = _get_Locale_impl( locale::classic()._M_impl ); 00113 return; 00114 } 00115 00116 _Locale_impl* impl = 0; 00117 _STLP_TRY { 00118 impl = new _Locale_impl(locale::id::_S_max, name); 00119 00120 // Insert categories one at a time. 00121 _Locale_name_hint *hint = 0; 00122 hint = impl->insert_ctype_facets(name, hint); 00123 hint = impl->insert_numeric_facets(name, hint); 00124 hint = impl->insert_time_facets(name, hint); 00125 hint = impl->insert_collate_facets(name, hint); 00126 hint = impl->insert_monetary_facets(name, hint); 00127 impl->insert_messages_facets(name, hint); 00128 // reassign impl 00129 _M_impl = _get_Locale_impl( impl ); 00130 } 00131 _STLP_UNWIND(delete impl); 00132 } 00133 00134 // Give L a name where all facets except those in category c 00135 // are taken from name1, and those in category c are taken from name2. 00136 static void _Stl_loc_combine_names(_Locale_impl* L, 00137 const char* name1, const char* name2, 00138 locale::category c) { 00139 if ((c & locale::all) == 0 || strcmp(name1, name2) == 0) 00140 L->name = name1; 00141 else if ((c & locale::all) == locale::all) 00142 L->name = name2; 00143 else { 00144 // Decompose the names. 00145 char ctype_buf[_Locale_MAX_SIMPLE_NAME]; 00146 char numeric_buf[_Locale_MAX_SIMPLE_NAME]; 00147 char time_buf[_Locale_MAX_SIMPLE_NAME]; 00148 char collate_buf[_Locale_MAX_SIMPLE_NAME]; 00149 char monetary_buf[_Locale_MAX_SIMPLE_NAME]; 00150 char messages_buf[_Locale_MAX_SIMPLE_NAME]; 00151 00152 // TODO: check returnvalues? 00153 _Locale_extract_ctype_name((c & locale::ctype) ? name2 : name1, ctype_buf, 0); 00154 _Locale_extract_numeric_name((c & locale::numeric) ? name2 : name1, numeric_buf, 0); 00155 _Locale_extract_time_name((c & locale::time) ? name2 : name1, time_buf, 0); 00156 _Locale_extract_collate_name((c & locale::collate) ? name2 : name1, collate_buf, 0); 00157 _Locale_extract_monetary_name((c & locale::monetary) ? name2 : name1, monetary_buf, 0); 00158 _Locale_extract_messages_name((c & locale::messages) ? name2 : name1, messages_buf, 0); 00159 00160 // Construct a new composite name. 00161 char composite_buf[_Locale_MAX_COMPOSITE_NAME]; 00162 // TODO: check returnvalue? 00163 _Locale_compose_name(composite_buf, 00164 ctype_buf, numeric_buf, time_buf, 00165 collate_buf, monetary_buf, messages_buf, 00166 name1); 00167 L->name = composite_buf; 00168 } 00169 } 00170 00171 // Create a locale that's a copy of L, except that all of the facets 00172 // in category c are instead constructed by name. 00173 locale::locale(const locale& L, const char* name, locale::category c) 00174 : _M_impl(0) { 00175 if (name == 0 || (_Nameless == name)) 00176 _M_throw_runtime_error(name); 00177 00178 _Locale_impl* impl = 0; 00179 00180 _STLP_TRY { 00181 impl = new _Locale_impl(*L._M_impl); 00182 _Stl_loc_combine_names(impl, L._M_impl->name.c_str(), name, c); 00183 00184 _Locale_name_hint *hint = 0; 00185 if (c & locale::ctype) 00186 hint = impl->insert_ctype_facets(name, hint); 00187 if (c & locale::numeric) 00188 hint = impl->insert_numeric_facets(name, hint); 00189 if (c & locale::time) 00190 hint = impl->insert_time_facets(name, hint); 00191 if (c & locale::collate) 00192 hint = impl->insert_collate_facets(name, hint); 00193 if (c & locale::monetary) 00194 hint = impl->insert_monetary_facets(name, hint); 00195 if (c & locale::messages) 00196 impl->insert_messages_facets(name, hint); 00197 _M_impl = _get_Locale_impl( impl ); 00198 } 00199 _STLP_UNWIND(delete impl) 00200 } 00201 00202 // Contruct a new locale where all facets that aren't in category c 00203 // come from L1, and all those that are in category c come from L2. 00204 locale::locale(const locale& L1, const locale& L2, category c) 00205 : _M_impl(0) { 00206 _Locale_impl* impl = new _Locale_impl(*L1._M_impl); 00207 00208 _Locale_impl* i2 = L2._M_impl; 00209 00210 if (L1.name() != _Nameless && L2.name() != _Nameless) 00211 _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c); 00212 else { 00213 impl->name = _Nameless; 00214 } 00215 00216 if (c & collate) { 00217 impl->insert( i2, _STLP_STD::collate<char>::id); 00218 # ifndef _STLP_NO_WCHAR_T 00219 impl->insert( i2, _STLP_STD::collate<wchar_t>::id); 00220 # endif 00221 } 00222 if (c & ctype) { 00223 impl->insert( i2, _STLP_STD::ctype<char>::id); 00224 impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id); 00225 # ifndef _STLP_NO_WCHAR_T 00226 impl->insert( i2, _STLP_STD::ctype<wchar_t>::id); 00227 impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id); 00228 # endif 00229 } 00230 if (c & monetary) { 00231 impl->insert( i2, _STLP_STD::moneypunct<char, true>::id); 00232 impl->insert( i2, _STLP_STD::moneypunct<char, false>::id); 00233 impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 00234 impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 00235 # ifndef _STLP_NO_WCHAR_T 00236 impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id); 00237 impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id); 00238 impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00239 impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00240 # endif 00241 } 00242 if (c & numeric) { 00243 impl->insert( i2, _STLP_STD::numpunct<char>::id); 00244 impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 00245 impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 00246 # ifndef _STLP_NO_WCHAR_T 00247 impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id); 00248 impl->insert( i2, num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00249 impl->insert( i2, num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00250 # endif 00251 } 00252 if (c & time) { 00253 impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 00254 impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 00255 # ifndef _STLP_NO_WCHAR_T 00256 impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00257 impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00258 # endif 00259 } 00260 if (c & messages) { 00261 impl->insert( i2, _STLP_STD::messages<char>::id); 00262 # ifndef _STLP_NO_WCHAR_T 00263 impl->insert( i2, _STLP_STD::messages<wchar_t>::id); 00264 # endif 00265 } 00266 _M_impl = _get_Locale_impl( impl ); 00267 } 00268 00269 // Destructor. 00270 locale::~locale() _STLP_NOTHROW { 00271 if (_M_impl) 00272 _release_Locale_impl(_M_impl); 00273 } 00274 00275 // Assignment operator. Much like the copy constructor: just a bit of 00276 // pointer twiddling. 00277 const locale& locale::operator=(const locale& L) _STLP_NOTHROW { 00278 if (this->_M_impl != L._M_impl) { 00279 if (this->_M_impl) 00280 _release_Locale_impl(this->_M_impl); 00281 this->_M_impl = _get_Locale_impl(L._M_impl); 00282 } 00283 return *this; 00284 } 00285 00286 locale::facet* locale::_M_get_facet(const locale::id& n) const { 00287 return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0; 00288 } 00289 00290 locale::facet* locale::_M_use_facet(const locale::id& n) const { 00291 locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0); 00292 if (!f) 00293 _M_impl->_M_throw_bad_cast(); 00294 return f; 00295 } 00296 00297 string locale::name() const { 00298 return _M_impl->name; 00299 } 00300 00301 // Compare two locales for equality. 00302 bool locale::operator==(const locale& L) const { 00303 return this->_M_impl == L._M_impl || 00304 (this->name() == L.name() && this->name() != _Nameless); 00305 } 00306 00307 bool locale::operator!=(const locale& L) const { 00308 return !(*this == L); 00309 } 00310 00311 // static data members. 00312 00313 const locale& _STLP_CALL locale::classic() { 00314 return *_Stl_get_classic_locale(); 00315 } 00316 00317 locale _STLP_CALL locale::global(const locale& L) { 00318 locale old(_Stl_get_global_locale()->_M_impl); 00319 if (_Stl_get_global_locale()->_M_impl != L._M_impl) { 00320 _release_Locale_impl(_Stl_get_global_locale()->_M_impl); 00321 // this assign should be atomic, should be fixed here: 00322 _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl); 00323 00324 // Set the global C locale, if appropriate. 00325 #if !defined(_STLP_NO_LOCALE_SUPPORT) 00326 if (L.name() != _Nameless) 00327 setlocale(LC_ALL, L.name().c_str()); 00328 #endif 00329 } 00330 00331 return old; 00332 } 00333 00334 # if !defined (_STLP_STATIC_CONST_INIT_BUG) && ! defined (_STLP_USE_DECLSPEC) 00335 00336 const locale::category locale::none; 00337 const locale::category locale::collate; 00338 const locale::category locale::ctype; 00339 const locale::category locale::monetary; 00340 const locale::category locale::numeric; 00341 const locale::category locale::time; 00342 const locale::category locale::messages; 00343 const locale::category locale::all; 00344 00345 # endif 00346 00347 _STLP_END_NAMESPACE 00348
Generated on Mon Mar 10 15:32:16 2008 by ![]() |