3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
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.
18 #include "stlport_prefix.h"
22 #include "message_facets.h"
23 #include "acquire_release.h"
27 _STLP_MOVE_TO_PRIV_NAMESPACE
29 void _Catalog_locale_map::insert(nl_catd_type key, const locale& L) {
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
36 typedef wchar_t _Char;
39 typedef ctype<_Char> wctype;
40 wctype const& wct = use_facet<wctype>(L);
41 if (typeid(wct) != typeid(wctype)) {
46 M->insert(map_type::value_type(key, L));
47 #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
54 void _Catalog_locale_map::erase(nl_catd_type key) {
59 locale _Catalog_locale_map::lookup(nl_catd_type key) const {
61 map_type::const_iterator i = M->find(key);
62 return i != M->end() ? (*i).second : locale::classic();
65 return locale::classic();
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];
75 #if defined (_STLP_ATOMIC_INCREMENT)
76 res = __STATIC_CAST(int, _STLP_ATOMIC_INCREMENT(&_count));
78 static _STLP_STATIC_MUTEX _Count_lock _STLP_MUTEX_INITIALIZER;
80 _STLP_auto_lock sentry(_Count_lock);
81 res = __STATIC_CAST(int, ++_count);
89 void _Catalog_nl_catd_map::erase(messages_base::catalog cat) {
90 map_type::iterator mit(M.find(cat));
92 Mr.erase((*mit).second);
98 //----------------------------------------------------------------------
100 _Messages::_Messages(bool is_wide, const char *name) :
101 _M_message_obj(0), _M_map(0) {
103 locale::_M_throw_on_null_name();
106 char buf[_Locale_MAX_SIMPLE_NAME];
107 _M_message_obj = _STLP_PRIV __acquire_messages(name, buf, 0, &__err_code);
109 locale::_M_throw_on_creation_failure(__err_code, name, "messages");
112 _M_map = new _Catalog_locale_map;
115 _Messages::_Messages(bool is_wide, _Locale_messages* msg) :
116 _M_message_obj(msg), _M_map(is_wide ? new _Catalog_locale_map() : 0)
119 _Messages::~_Messages() {
120 __release_messages(_M_message_obj);
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) ) {
130 _M_map->insert(result, L);
132 return _STLP_MUTABLE(_Messages_impl, _M_cat).insert( result );
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()))
146 #if !defined (_STLP_NO_WCHAR_T)
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.
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')))
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());
177 void _Messages::do_close(catalog thecat) const {
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 );
184 _STLP_MOVE_TO_STD_NAMESPACE
186 //----------------------------------------------------------------------
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()
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); }
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 //----------------------------------------------------------------------
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()
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); }
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); }