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
); }