123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- /*
- * Copyright (c) 1999
- * Silicon Graphics Computer Systems, Inc.
- *
- * Copyright (c) 1999
- * Boris Fomitchev
- *
- * This material is provided "as is", with absolutely no warranty expressed
- * or implied. Any use is at your own risk.
- *
- * Permission to use or copy this software for any purpose is hereby granted
- * without fee, provided the above notices are retained on all copies.
- * Permission to modify the code and to distribute modified code is granted,
- * provided the above notices are retained, and a notice that the code was
- * modified is included with the above copyright notice.
- *
- */
- #include "stlport_prefix.h"
- #include <typeinfo>
- #include "message_facets.h"
- #include "acquire_release.h"
- _STLP_BEGIN_NAMESPACE
- _STLP_MOVE_TO_PRIV_NAMESPACE
- void _Catalog_locale_map::insert(nl_catd_type key, const locale& L) {
- _STLP_TRY {
- #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
- // Don't bother to do anything unless we're using a non-default ctype facet
- # ifdef _STLP_NO_WCHAR_T
- typedef char _Char;
- # else
- typedef wchar_t _Char;
- # endif
- typedef ctype<_Char> wctype;
- wctype const& wct = use_facet<wctype>(L);
- if (typeid(wct) != typeid(wctype)) {
- #endif
- if (!M)
- M = new map_type;
- M->insert(map_type::value_type(key, L));
- #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
- }
- #endif
- }
- _STLP_CATCH_ALL {}
- }
- void _Catalog_locale_map::erase(nl_catd_type key) {
- if (M)
- M->erase(key);
- }
- locale _Catalog_locale_map::lookup(nl_catd_type key) const {
- if (M) {
- map_type::const_iterator i = M->find(key);
- return i != M->end() ? (*i).second : locale::classic();
- }
- else
- return locale::classic();
- }
- #if defined (_STLP_USE_NL_CATD_MAPPING)
- _STLP_VOLATILE __stl_atomic_t _Catalog_nl_catd_map::_count = 0;
- messages_base::catalog _Catalog_nl_catd_map::insert(nl_catd_type cat) {
- messages_base::catalog &res = Mr[cat];
- if ( res == 0 ) {
- #if defined (_STLP_ATOMIC_INCREMENT)
- res = __STATIC_CAST(int, _STLP_ATOMIC_INCREMENT(&_count));
- #else
- static _STLP_STATIC_MUTEX _Count_lock _STLP_MUTEX_INITIALIZER;
- {
- _STLP_auto_lock sentry(_Count_lock);
- res = __STATIC_CAST(int, ++_count);
- }
- #endif
- M[res] = cat;
- }
- return res;
- }
- void _Catalog_nl_catd_map::erase(messages_base::catalog cat) {
- map_type::iterator mit(M.find(cat));
- if (mit != M.end()) {
- Mr.erase((*mit).second);
- M.erase(mit);
- }
- }
- #endif
- //----------------------------------------------------------------------
- //
- _Messages::_Messages(bool is_wide, const char *name) :
- _M_message_obj(0), _M_map(0) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_message_obj = _STLP_PRIV __acquire_messages(name, buf, 0, &__err_code);
- if (!_M_message_obj)
- locale::_M_throw_on_creation_failure(__err_code, name, "messages");
- if (is_wide)
- _M_map = new _Catalog_locale_map;
- }
- _Messages::_Messages(bool is_wide, _Locale_messages* msg) :
- _M_message_obj(msg), _M_map(is_wide ? new _Catalog_locale_map() : 0)
- {}
- _Messages::~_Messages() {
- __release_messages(_M_message_obj);
- delete _M_map;
- }
- _Messages::catalog _Messages::do_open(const string& filename, const locale& L) const {
- nl_catd_type result = _M_message_obj ? _Locale_catopen(_M_message_obj, filename.c_str())
- : (nl_catd_type)(-1);
- if ( result != (nl_catd_type)(-1) ) {
- if ( _M_map != 0 ) {
- _M_map->insert(result, L);
- }
- return _STLP_MUTABLE(_Messages_impl, _M_cat).insert( result );
- }
- return -1;
- }
- string _Messages::do_get(catalog cat,
- int set, int p_id, const string& dfault) const {
- return _M_message_obj != 0 && cat >= 0
- ? string(_Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[cat],
- set, p_id, dfault.c_str()))
- : dfault;
- }
- #if !defined (_STLP_NO_WCHAR_T)
- wstring
- _Messages::do_get(catalog thecat,
- int set, int p_id, const wstring& dfault) const {
- typedef ctype<wchar_t> wctype;
- const wctype& ct = use_facet<wctype>(_M_map->lookup(_STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]));
- const char* str = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, "");
- // Verify that the lookup failed; an empty string might represent success.
- if (!str)
- return dfault;
- else if (str[0] == '\0') {
- const char* str2 = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, "*");
- if (!str2 || ((str2[0] == '*') && (str2[1] == '\0')))
- return dfault;
- }
- // str is correct. Now we must widen it to get a wstring.
- size_t n = strlen(str);
- // NOT PORTABLE. What we're doing relies on internal details of the
- // string implementation. (Contiguity of string elements.)
- wstring result(n, wchar_t(0));
- ct.widen(str, str + n, &*result.begin());
- return result;
- }
- #endif
- void _Messages::do_close(catalog thecat) const {
- if (_M_message_obj)
- _Locale_catclose(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]);
- if (_M_map) _M_map->erase(_STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]);
- _STLP_MUTABLE(_Messages_impl, _M_cat).erase( thecat );
- }
- _STLP_MOVE_TO_STD_NAMESPACE
- //----------------------------------------------------------------------
- // messages<char>
- messages<char>::messages(size_t refs)
- : locale::facet(refs) {}
- messages_byname<char>::messages_byname(const char *name, size_t refs)
- : messages<char>(refs), _M_impl(new _STLP_PRIV _Messages(false, name)) {}
- messages_byname<char>::messages_byname(_Locale_messages* msg)
- : messages<char>(0), _M_impl(new _STLP_PRIV _Messages(false, msg)) {}
- messages_byname<char>::~messages_byname()
- { delete _M_impl; }
- messages_byname<char>::catalog
- messages_byname<char>::do_open(const string& filename, const locale& l) const
- { return _M_impl->do_open(filename, l); }
- string
- messages_byname<char>::do_get(catalog cat, int set, int p_id,
- const string& dfault) const
- { return _M_impl->do_get(cat, set, p_id, dfault); }
- void messages_byname<char>::do_close(catalog cat) const
- { _M_impl->do_close(cat); }
- #if !defined (_STLP_NO_WCHAR_T)
- //----------------------------------------------------------------------
- // messages<wchar_t>
- messages<wchar_t>::messages(size_t refs)
- : locale::facet(refs) {}
- messages_byname<wchar_t>::messages_byname(const char *name, size_t refs)
- : messages<wchar_t>(refs), _M_impl(new _STLP_PRIV _Messages(true, name)) {}
- messages_byname<wchar_t>::messages_byname(_Locale_messages* msg)
- : messages<wchar_t>(0), _M_impl(new _STLP_PRIV _Messages(true, msg)) {}
- messages_byname<wchar_t>::~messages_byname()
- { delete _M_impl; }
- messages_byname<wchar_t>::catalog
- messages_byname<wchar_t>::do_open(const string& filename, const locale& L) const
- { return _M_impl->do_open(filename, L); }
- wstring
- messages_byname<wchar_t>::do_get(catalog thecat,
- int set, int p_id, const wstring& dfault) const
- { return _M_impl->do_get(thecat, set, p_id, dfault); }
- void messages_byname<wchar_t>::do_close(catalog cat) const
- { _M_impl->do_close(cat); }
- #endif
- _STLP_END_NAMESPACE
- // Local Variables:
- // mode:C++
- // End:
|