|
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" |
|
19 |
|
20 #include <typeinfo> |
|
21 |
|
22 #include "message_facets.h" |
|
23 #include "acquire_release.h" |
|
24 |
|
25 _STLP_BEGIN_NAMESPACE |
|
26 |
|
27 _STLP_MOVE_TO_PRIV_NAMESPACE |
|
28 |
|
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 |
|
38 |
|
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; |
|
45 |
|
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 } |
|
53 |
|
54 void _Catalog_locale_map::erase(nl_catd_type key) { |
|
55 if (M) |
|
56 M->erase(key); |
|
57 } |
|
58 |
|
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 } |
|
67 |
|
68 |
|
69 #if defined (_STLP_USE_NL_CATD_MAPPING) |
|
70 _STLP_VOLATILE __stl_atomic_t _Catalog_nl_catd_map::_count = 0; |
|
71 |
|
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 } |
|
88 |
|
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 |
|
97 |
|
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(); |
|
104 |
|
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"); |
|
110 |
|
111 if (is_wide) |
|
112 _M_map = new _Catalog_locale_map; |
|
113 } |
|
114 |
|
115 _Messages::_Messages(bool is_wide, _Locale_messages* msg) : |
|
116 _M_message_obj(msg), _M_map(is_wide ? new _Catalog_locale_map() : 0) |
|
117 {} |
|
118 |
|
119 _Messages::~_Messages() { |
|
120 __release_messages(_M_message_obj); |
|
121 delete _M_map; |
|
122 } |
|
123 |
|
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); |
|
127 |
|
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 } |
|
134 |
|
135 return -1; |
|
136 } |
|
137 |
|
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 } |
|
145 |
|
146 #if !defined (_STLP_NO_WCHAR_T) |
|
147 |
|
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])); |
|
153 |
|
154 const char* str = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, ""); |
|
155 |
|
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 } |
|
164 |
|
165 // str is correct. Now we must widen it to get a wstring. |
|
166 size_t n = strlen(str); |
|
167 |
|
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 } |
|
174 |
|
175 #endif |
|
176 |
|
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 } |
|
183 |
|
184 _STLP_MOVE_TO_STD_NAMESPACE |
|
185 |
|
186 //---------------------------------------------------------------------- |
|
187 // messages<char> |
|
188 messages<char>::messages(size_t refs) |
|
189 : locale::facet(refs) {} |
|
190 |
|
191 messages_byname<char>::messages_byname(const char *name, size_t refs) |
|
192 : messages<char>(refs), _M_impl(new _STLP_PRIV _Messages(false, name)) {} |
|
193 |
|
194 messages_byname<char>::messages_byname(_Locale_messages* msg) |
|
195 : messages<char>(0), _M_impl(new _STLP_PRIV _Messages(false, msg)) {} |
|
196 |
|
197 messages_byname<char>::~messages_byname() |
|
198 { delete _M_impl; } |
|
199 |
|
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); } |
|
203 |
|
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); } |
|
208 |
|
209 void messages_byname<char>::do_close(catalog cat) const |
|
210 { _M_impl->do_close(cat); } |
|
211 |
|
212 #if !defined (_STLP_NO_WCHAR_T) |
|
213 |
|
214 //---------------------------------------------------------------------- |
|
215 // messages<wchar_t> |
|
216 |
|
217 messages<wchar_t>::messages(size_t refs) |
|
218 : locale::facet(refs) {} |
|
219 |
|
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)) {} |
|
222 |
|
223 messages_byname<wchar_t>::messages_byname(_Locale_messages* msg) |
|
224 : messages<wchar_t>(0), _M_impl(new _STLP_PRIV _Messages(true, msg)) {} |
|
225 |
|
226 messages_byname<wchar_t>::~messages_byname() |
|
227 { delete _M_impl; } |
|
228 |
|
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); } |
|
232 |
|
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); } |
|
237 |
|
238 void messages_byname<wchar_t>::do_close(catalog cat) const |
|
239 { _M_impl->do_close(cat); } |
|
240 |
|
241 #endif |
|
242 |
|
243 _STLP_END_NAMESPACE |
|
244 |
|
245 // Local Variables: |
|
246 // mode:C++ |
|
247 // End: |