build/stlport/src/messages.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  * Copyright (c) 1999
     3  * Silicon Graphics Computer Systems, Inc.
     4  *
     5  * Copyright (c) 1999
     6  * Boris Fomitchev
     7  *
     8  * This material is provided "as is", with absolutely no warranty expressed
     9  * or implied. Any use is at your own risk.
    10  *
    11  * Permission to use or copy this software for any purpose is hereby granted
    12  * without fee, provided the above notices are retained on all copies.
    13  * Permission to modify the code and to distribute modified code is granted,
    14  * provided the above notices are retained, and a notice that the code was
    15  * modified is included with the above copyright notice.
    16  *
    17  */
    18 #include "stlport_prefix.h"
    20 #include <typeinfo>
    22 #include "message_facets.h"
    23 #include "acquire_release.h"
    25 _STLP_BEGIN_NAMESPACE
    27 _STLP_MOVE_TO_PRIV_NAMESPACE
    29 void _Catalog_locale_map::insert(nl_catd_type key, const locale& L) {
    30   _STLP_TRY {
    31 #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
    32     // Don't bother to do anything unless we're using a non-default ctype facet
    33 #  ifdef _STLP_NO_WCHAR_T
    34     typedef char _Char;
    35 #  else
    36     typedef wchar_t _Char;
    37 #  endif
    39     typedef ctype<_Char> wctype;
    40     wctype const& wct = use_facet<wctype>(L);
    41     if (typeid(wct) != typeid(wctype)) {
    42 #endif
    43       if (!M)
    44         M = new map_type;
    46       M->insert(map_type::value_type(key, L));
    47 #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
    48     }
    49 #endif
    50   }
    51   _STLP_CATCH_ALL {}
    52 }
    54 void _Catalog_locale_map::erase(nl_catd_type key) {
    55   if (M)
    56     M->erase(key);
    57 }
    59 locale _Catalog_locale_map::lookup(nl_catd_type key) const {
    60   if (M) {
    61     map_type::const_iterator i = M->find(key);
    62     return i != M->end() ? (*i).second : locale::classic();
    63   }
    64   else
    65     return locale::classic();
    66 }
    69 #if defined (_STLP_USE_NL_CATD_MAPPING)
    70 _STLP_VOLATILE __stl_atomic_t _Catalog_nl_catd_map::_count = 0;
    72 messages_base::catalog _Catalog_nl_catd_map::insert(nl_catd_type cat) {
    73   messages_base::catalog &res = Mr[cat];
    74   if ( res == 0 ) {
    75 #if defined (_STLP_ATOMIC_INCREMENT)
    76     res = __STATIC_CAST(int, _STLP_ATOMIC_INCREMENT(&_count));
    77 #else
    78     static _STLP_STATIC_MUTEX _Count_lock _STLP_MUTEX_INITIALIZER;
    79     {
    80       _STLP_auto_lock sentry(_Count_lock);
    81       res = __STATIC_CAST(int, ++_count);
    82     }
    83 #endif
    84     M[res] = cat;
    85   }
    86   return res;
    87 }
    89 void _Catalog_nl_catd_map::erase(messages_base::catalog cat) {
    90   map_type::iterator mit(M.find(cat));
    91   if (mit != M.end()) {
    92     Mr.erase((*mit).second);
    93     M.erase(mit);
    94   }
    95 }
    96 #endif
    98 //----------------------------------------------------------------------
    99 //
   100 _Messages::_Messages(bool is_wide, const char *name) :
   101   _M_message_obj(0), _M_map(0) {
   102   if (!name)
   103     locale::_M_throw_on_null_name();
   105   int __err_code;
   106   char buf[_Locale_MAX_SIMPLE_NAME];
   107   _M_message_obj = _STLP_PRIV __acquire_messages(name, buf, 0, &__err_code);
   108   if (!_M_message_obj)
   109     locale::_M_throw_on_creation_failure(__err_code, name, "messages");
   111   if (is_wide)
   112     _M_map = new _Catalog_locale_map;
   113 }
   115 _Messages::_Messages(bool is_wide, _Locale_messages* msg) :
   116   _M_message_obj(msg), _M_map(is_wide ? new _Catalog_locale_map() : 0)
   117 {}
   119 _Messages::~_Messages() {
   120   __release_messages(_M_message_obj);
   121   delete _M_map;
   122 }
   124 _Messages::catalog _Messages::do_open(const string& filename, const locale& L) const {
   125   nl_catd_type result = _M_message_obj ? _Locale_catopen(_M_message_obj, filename.c_str())
   126     : (nl_catd_type)(-1);
   128   if ( result != (nl_catd_type)(-1) ) {
   129     if ( _M_map != 0 ) {
   130       _M_map->insert(result, L);
   131     }
   132     return _STLP_MUTABLE(_Messages_impl, _M_cat).insert( result );
   133   }
   135   return -1;
   136 }
   138 string _Messages::do_get(catalog cat,
   139                          int set, int p_id, const string& dfault) const {
   140   return _M_message_obj != 0 && cat >= 0
   141     ? string(_Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[cat],
   142                              set, p_id, dfault.c_str()))
   143     : dfault;
   144 }
   146 #if !defined (_STLP_NO_WCHAR_T)
   148 wstring
   149 _Messages::do_get(catalog thecat,
   150                   int set, int p_id, const wstring& dfault) const {
   151   typedef ctype<wchar_t> wctype;
   152   const wctype& ct = use_facet<wctype>(_M_map->lookup(_STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]));
   154   const char* str = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, "");
   156   // Verify that the lookup failed; an empty string might represent success.
   157   if (!str)
   158     return dfault;
   159   else if (str[0] == '\0') {
   160     const char* str2 = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, "*");
   161     if (!str2 || ((str2[0] == '*') && (str2[1] == '\0')))
   162       return dfault;
   163   }
   165   // str is correct.  Now we must widen it to get a wstring.
   166   size_t n = strlen(str);
   168   // NOT PORTABLE.  What we're doing relies on internal details of the
   169   // string implementation.  (Contiguity of string elements.)
   170   wstring result(n, wchar_t(0));
   171   ct.widen(str, str + n, &*result.begin());
   172   return result;
   173 }
   175 #endif
   177 void _Messages::do_close(catalog thecat) const {
   178   if (_M_message_obj)
   179     _Locale_catclose(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]);
   180   if (_M_map) _M_map->erase(_STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]);
   181   _STLP_MUTABLE(_Messages_impl, _M_cat).erase( thecat );
   182 }
   184 _STLP_MOVE_TO_STD_NAMESPACE
   186 //----------------------------------------------------------------------
   187 // messages<char>
   188 messages<char>::messages(size_t refs)
   189   : locale::facet(refs) {}
   191 messages_byname<char>::messages_byname(const char *name, size_t refs)
   192   : messages<char>(refs), _M_impl(new _STLP_PRIV _Messages(false, name)) {}
   194 messages_byname<char>::messages_byname(_Locale_messages* msg)
   195   : messages<char>(0), _M_impl(new _STLP_PRIV _Messages(false, msg)) {}
   197 messages_byname<char>::~messages_byname()
   198 { delete _M_impl; }
   200 messages_byname<char>::catalog
   201 messages_byname<char>::do_open(const string& filename, const locale& l) const
   202 { return _M_impl->do_open(filename, l); }
   204 string
   205 messages_byname<char>::do_get(catalog cat, int set, int p_id,
   206                               const string& dfault) const
   207 { return _M_impl->do_get(cat, set, p_id, dfault); }
   209 void messages_byname<char>::do_close(catalog cat) const
   210 { _M_impl->do_close(cat); }
   212 #if !defined (_STLP_NO_WCHAR_T)
   214 //----------------------------------------------------------------------
   215 // messages<wchar_t>
   217 messages<wchar_t>::messages(size_t refs)
   218   : locale::facet(refs) {}
   220 messages_byname<wchar_t>::messages_byname(const char *name, size_t refs)
   221   : messages<wchar_t>(refs), _M_impl(new _STLP_PRIV _Messages(true, name)) {}
   223 messages_byname<wchar_t>::messages_byname(_Locale_messages* msg)
   224   : messages<wchar_t>(0), _M_impl(new _STLP_PRIV _Messages(true, msg)) {}
   226 messages_byname<wchar_t>::~messages_byname()
   227 { delete _M_impl; }
   229 messages_byname<wchar_t>::catalog
   230 messages_byname<wchar_t>::do_open(const string& filename, const locale& L) const
   231 { return _M_impl->do_open(filename, L); }
   233 wstring
   234 messages_byname<wchar_t>::do_get(catalog thecat,
   235                                  int set, int p_id, const wstring& dfault) const
   236 { return _M_impl->do_get(thecat, set, p_id, dfault); }
   238 void messages_byname<wchar_t>::do_close(catalog cat) const
   239 { _M_impl->do_close(cat); }
   241 #endif
   243 _STLP_END_NAMESPACE
   245 // Local Variables:
   246 // mode:C++
   247 // End:

mercurial