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 #ifndef MESSAGE_FACETS_H 19 #define MESSAGE_FACETS_H 20 21 #include <string> 22 #include <locale> 23 #include <typeinfo> 24 #include <hash_map> 25 26 #include "c_locale.h" 27 #include "acquire_release.h" 28 29 _STLP_BEGIN_NAMESPACE 30 _STLP_MOVE_TO_PRIV_NAMESPACE 31 32 // Class _Catalog_locale_map. The reason for this is that, internally, 33 // a message string is always a char*. We need a ctype facet to convert 34 // a string to and from wchar_t, and the user is permitted to provide such 35 // a facet when calling open(). 36 37 struct _Catalog_locale_map { _Catalog_locale_map_Catalog_locale_map38 _Catalog_locale_map() : M(0) {} ~_Catalog_locale_map_Catalog_locale_map39 ~_Catalog_locale_map() { if (M) delete M; } 40 41 void insert(nl_catd_type key, const locale& L); 42 locale lookup(nl_catd_type key) const; 43 void erase(nl_catd_type key); 44 45 typedef hash_map<nl_catd_type, locale, hash<nl_catd_type>, equal_to<nl_catd_type> > map_type; 46 map_type *M; 47 48 private: // Invalidate copy constructor and assignment 49 _Catalog_locale_map(const _Catalog_locale_map&); 50 void operator=(const _Catalog_locale_map&); 51 }; 52 53 /* 54 * In glibc nl_catd type is void *, but messages_base::catalog is defined as int 55 * by ISO/IEC 14882; The int may be too short to store pointer on 64-bit platforms; 56 * Another problem, is that do_open() may return negative value to indicate that no 57 * catalog open---this case can't be represented with pointers. 58 * The class _Catalog_nl_catd_map intended to make relation between 59 * messages_base::catalog and nl_catd handler. 60 * 61 */ 62 63 #if defined (_STLP_REAL_LOCALE_IMPLEMENTED) && (defined (_STLP_USE_GLIBC) && !defined (__CYGWIN__)) 64 # define _STLP_USE_NL_CATD_MAPPING 65 #else 66 /* If no mapping a message_base::catalog entry, int typedef according C++ Standard 22.2.7.1, 67 * has to be large enough to contain a nl_catd_type value. 68 */ 69 _STLP_STATIC_ASSERT(sizeof(nl_catd_type) <= sizeof(int)) 70 #endif 71 72 class _STLP_CLASS_DECLSPEC _Catalog_nl_catd_map { 73 public: _Catalog_nl_catd_map()74 _Catalog_nl_catd_map() 75 {} ~_Catalog_nl_catd_map()76 ~_Catalog_nl_catd_map() 77 {} 78 79 typedef hash_map<messages_base::catalog, nl_catd_type, hash<messages_base::catalog>, equal_to<messages_base::catalog> > map_type; 80 typedef hash_map<nl_catd_type, messages_base::catalog, hash<nl_catd_type>, equal_to<nl_catd_type> > rmap_type; 81 // typedef map<messages_base::catalog,nl_catd_type> map_type; 82 // typedef map<nl_catd_type,messages_base::catalog> rmap_type; 83 insert(nl_catd_type cat)84 messages_base::catalog insert(nl_catd_type cat) 85 #if !defined (_STLP_USE_NL_CATD_MAPPING) 86 { return (messages_base::catalog)cat; } 87 #else 88 ; 89 #endif 90 erase(messages_base::catalog)91 void erase(messages_base::catalog) 92 #if !defined (_STLP_USE_NL_CATD_MAPPING) 93 {} 94 #else 95 ; 96 #endif 97 98 nl_catd_type operator [] ( messages_base::catalog cat ) const 99 #if !defined (_STLP_USE_NL_CATD_MAPPING) 100 { return cat; } 101 #else 102 { return cat < 0 ? 0 : M[cat]; } 103 #endif 104 105 private: 106 _Catalog_nl_catd_map(const _Catalog_nl_catd_map&); 107 _Catalog_nl_catd_map& operator =(const _Catalog_nl_catd_map&); 108 109 #if defined (_STLP_USE_NL_CATD_MAPPING) 110 mutable map_type M; 111 mutable rmap_type Mr; 112 static _STLP_VOLATILE __stl_atomic_t _count; 113 #endif 114 }; 115 116 class _STLP_CLASS_DECLSPEC _Messages { 117 public: 118 typedef messages_base::catalog catalog; 119 120 _Messages(); 121 122 virtual catalog do_open(const string& __fn, const locale& __loc) const; 123 virtual string do_get(catalog __c, int __set, int __msgid, 124 const string& __dfault) const; 125 #if !defined (_STLP_NO_WCHAR_T) 126 virtual wstring do_get(catalog __c, int __set, int __msgid, 127 const wstring& __dfault) const; 128 #endif 129 virtual void do_close(catalog __c) const; 130 virtual ~_Messages(); 131 bool _M_delete; 132 }; 133 134 class _STLP_CLASS_DECLSPEC _Messages_impl : public _Messages { 135 public: 136 _Messages_impl(bool, _Locale_name_hint* hint = 0); 137 _Messages_impl(bool, _Locale_messages*); 138 139 catalog do_open(const string& __fn, const locale& __loc) const; 140 string do_get(catalog __c, int __set, int __msgid, 141 const string& __dfault) const; 142 #if !defined (_STLP_NO_WCHAR_T) 143 wstring do_get(catalog __c, int __set, int __msgid, 144 const wstring& __dfault) const; 145 #endif 146 void do_close(catalog __c) const; 147 148 ~_Messages_impl(); 149 150 private: 151 _Locale_messages* _M_message_obj; 152 _Catalog_locale_map* _M_map; 153 mutable _Catalog_nl_catd_map _M_cat; 154 155 //private definition to avoid warning (with ICL) 156 _Messages_impl(const _Messages_impl&); 157 _Messages_impl& operator=(const _Messages_impl&); 158 }; 159 160 _STLP_MOVE_TO_STD_NAMESPACE 161 162 _STLP_END_NAMESPACE 163 164 #endif 165 166 // Local Variables: 167 // mode:C++ 168 // End: 169