messages.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. #include <typeinfo>
  20. #include "message_facets.h"
  21. #include "acquire_release.h"
  22. _STLP_BEGIN_NAMESPACE
  23. _STLP_MOVE_TO_PRIV_NAMESPACE
  24. void _Catalog_locale_map::insert(nl_catd_type key, const locale& L) {
  25. _STLP_TRY {
  26. #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
  27. // Don't bother to do anything unless we're using a non-default ctype facet
  28. # ifdef _STLP_NO_WCHAR_T
  29. typedef char _Char;
  30. # else
  31. typedef wchar_t _Char;
  32. # endif
  33. typedef ctype<_Char> wctype;
  34. wctype const& wct = use_facet<wctype>(L);
  35. if (typeid(wct) != typeid(wctype)) {
  36. #endif
  37. if (!M)
  38. M = new map_type;
  39. M->insert(map_type::value_type(key, L));
  40. #if !defined (_STLP_NO_TYPEINFO) && !defined (_STLP_NO_RTTI)
  41. }
  42. #endif
  43. }
  44. _STLP_CATCH_ALL {}
  45. }
  46. void _Catalog_locale_map::erase(nl_catd_type key) {
  47. if (M)
  48. M->erase(key);
  49. }
  50. locale _Catalog_locale_map::lookup(nl_catd_type key) const {
  51. if (M) {
  52. map_type::const_iterator i = M->find(key);
  53. return i != M->end() ? (*i).second : locale::classic();
  54. }
  55. else
  56. return locale::classic();
  57. }
  58. #if defined (_STLP_USE_NL_CATD_MAPPING)
  59. _STLP_VOLATILE __stl_atomic_t _Catalog_nl_catd_map::_count = 0;
  60. messages_base::catalog _Catalog_nl_catd_map::insert(nl_catd_type cat) {
  61. messages_base::catalog &res = Mr[cat];
  62. if ( res == 0 ) {
  63. #if defined (_STLP_ATOMIC_INCREMENT)
  64. res = __STATIC_CAST(int, _STLP_ATOMIC_INCREMENT(&_count));
  65. #else
  66. static _STLP_STATIC_MUTEX _Count_lock _STLP_MUTEX_INITIALIZER;
  67. {
  68. _STLP_auto_lock sentry(_Count_lock);
  69. res = __STATIC_CAST(int, ++_count);
  70. }
  71. #endif
  72. M[res] = cat;
  73. }
  74. return res;
  75. }
  76. void _Catalog_nl_catd_map::erase(messages_base::catalog cat) {
  77. map_type::iterator mit(M.find(cat));
  78. if (mit != M.end()) {
  79. Mr.erase((*mit).second);
  80. M.erase(mit);
  81. }
  82. }
  83. #endif
  84. //----------------------------------------------------------------------
  85. //
  86. _Messages::_Messages(bool is_wide, const char *name) :
  87. _M_message_obj(0), _M_map(0) {
  88. if (!name)
  89. locale::_M_throw_on_null_name();
  90. int __err_code;
  91. char buf[_Locale_MAX_SIMPLE_NAME];
  92. _M_message_obj = _STLP_PRIV __acquire_messages(name, buf, 0, &__err_code);
  93. if (!_M_message_obj)
  94. locale::_M_throw_on_creation_failure(__err_code, name, "messages");
  95. if (is_wide)
  96. _M_map = new _Catalog_locale_map;
  97. }
  98. _Messages::_Messages(bool is_wide, _Locale_messages* msg) :
  99. _M_message_obj(msg), _M_map(is_wide ? new _Catalog_locale_map() : 0)
  100. {}
  101. _Messages::~_Messages() {
  102. __release_messages(_M_message_obj);
  103. delete _M_map;
  104. }
  105. _Messages::catalog _Messages::do_open(const string& filename, const locale& L) const {
  106. nl_catd_type result = _M_message_obj ? _Locale_catopen(_M_message_obj, filename.c_str())
  107. : (nl_catd_type)(-1);
  108. if ( result != (nl_catd_type)(-1) ) {
  109. if ( _M_map != 0 ) {
  110. _M_map->insert(result, L);
  111. }
  112. return _STLP_MUTABLE(_Messages_impl, _M_cat).insert( result );
  113. }
  114. return -1;
  115. }
  116. string _Messages::do_get(catalog cat,
  117. int set, int p_id, const string& dfault) const {
  118. return _M_message_obj != 0 && cat >= 0
  119. ? string(_Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[cat],
  120. set, p_id, dfault.c_str()))
  121. : dfault;
  122. }
  123. #if !defined (_STLP_NO_WCHAR_T)
  124. wstring
  125. _Messages::do_get(catalog thecat,
  126. int set, int p_id, const wstring& dfault) const {
  127. typedef ctype<wchar_t> wctype;
  128. const wctype& ct = use_facet<wctype>(_M_map->lookup(_STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]));
  129. const char* str = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, "");
  130. // Verify that the lookup failed; an empty string might represent success.
  131. if (!str)
  132. return dfault;
  133. else if (str[0] == '\0') {
  134. const char* str2 = _Locale_catgets(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat], set, p_id, "*");
  135. if (!str2 || ((str2[0] == '*') && (str2[1] == '\0')))
  136. return dfault;
  137. }
  138. // str is correct. Now we must widen it to get a wstring.
  139. size_t n = strlen(str);
  140. // NOT PORTABLE. What we're doing relies on internal details of the
  141. // string implementation. (Contiguity of string elements.)
  142. wstring result(n, wchar_t(0));
  143. ct.widen(str, str + n, &*result.begin());
  144. return result;
  145. }
  146. #endif
  147. void _Messages::do_close(catalog thecat) const {
  148. if (_M_message_obj)
  149. _Locale_catclose(_M_message_obj, _STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]);
  150. if (_M_map) _M_map->erase(_STLP_MUTABLE(_Messages_impl, _M_cat)[thecat]);
  151. _STLP_MUTABLE(_Messages_impl, _M_cat).erase( thecat );
  152. }
  153. _STLP_MOVE_TO_STD_NAMESPACE
  154. //----------------------------------------------------------------------
  155. // messages<char>
  156. messages<char>::messages(size_t refs)
  157. : locale::facet(refs) {}
  158. messages_byname<char>::messages_byname(const char *name, size_t refs)
  159. : messages<char>(refs), _M_impl(new _STLP_PRIV _Messages(false, name)) {}
  160. messages_byname<char>::messages_byname(_Locale_messages* msg)
  161. : messages<char>(0), _M_impl(new _STLP_PRIV _Messages(false, msg)) {}
  162. messages_byname<char>::~messages_byname()
  163. { delete _M_impl; }
  164. messages_byname<char>::catalog
  165. messages_byname<char>::do_open(const string& filename, const locale& l) const
  166. { return _M_impl->do_open(filename, l); }
  167. string
  168. messages_byname<char>::do_get(catalog cat, int set, int p_id,
  169. const string& dfault) const
  170. { return _M_impl->do_get(cat, set, p_id, dfault); }
  171. void messages_byname<char>::do_close(catalog cat) const
  172. { _M_impl->do_close(cat); }
  173. #if !defined (_STLP_NO_WCHAR_T)
  174. //----------------------------------------------------------------------
  175. // messages<wchar_t>
  176. messages<wchar_t>::messages(size_t refs)
  177. : locale::facet(refs) {}
  178. messages_byname<wchar_t>::messages_byname(const char *name, size_t refs)
  179. : messages<wchar_t>(refs), _M_impl(new _STLP_PRIV _Messages(true, name)) {}
  180. messages_byname<wchar_t>::messages_byname(_Locale_messages* msg)
  181. : messages<wchar_t>(0), _M_impl(new _STLP_PRIV _Messages(true, msg)) {}
  182. messages_byname<wchar_t>::~messages_byname()
  183. { delete _M_impl; }
  184. messages_byname<wchar_t>::catalog
  185. messages_byname<wchar_t>::do_open(const string& filename, const locale& L) const
  186. { return _M_impl->do_open(filename, L); }
  187. wstring
  188. messages_byname<wchar_t>::do_get(catalog thecat,
  189. int set, int p_id, const wstring& dfault) const
  190. { return _M_impl->do_get(thecat, set, p_id, dfault); }
  191. void messages_byname<wchar_t>::do_close(catalog cat) const
  192. { _M_impl->do_close(cat); }
  193. #endif
  194. _STLP_END_NAMESPACE
  195. // Local Variables:
  196. // mode:C++
  197. // End: