ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

locale_catalog.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 #include "stlport_prefix.h"
00019 
00020 #include <hash_map>
00021 #include <string>
00022 
00023 #include <locale>
00024 #include <istream>
00025 
00026 #include "c_locale.h"
00027 #include "locale_impl.h"
00028 #include "acquire_release.h"
00029 
00030 _STLP_BEGIN_NAMESPACE
00031 _STLP_MOVE_TO_PRIV_NAMESPACE
00032 
00033 // Those wrappers are needed to use locale functions in __acquire_category,
00034 // all functions have to present the same prototype.
00035 
00036 static void* _Loc_ctype_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00037 { return _Locale_ctype_create(s, hint, __err_code); }
00038 static void* _Loc_codecvt_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00039 { return _Locale_codecvt_create(s, hint, __err_code); }
00040 static void* _Loc_numeric_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00041 { return _Locale_numeric_create(s, hint, __err_code); }
00042 static void* _Loc_time_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00043 { return _Locale_time_create(s, hint, __err_code); }
00044 static void* _Loc_collate_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00045 { return _Locale_collate_create(s, hint, __err_code); }
00046 static void* _Loc_monetary_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00047 { return _Locale_monetary_create(s, hint, __err_code); }
00048 static void* _Loc_messages_create(const char * s, _Locale_name_hint* hint, int *__err_code)
00049 { return _Locale_messages_create(s, hint, __err_code); }
00050 
00051 static char const* _Loc_ctype_name(void* l, char* s)
00052 { return _Locale_ctype_name((_Locale_ctype*)l, s); }
00053 static char const* _Loc_codecvt_name(void* l, char* s)
00054 { return _Locale_codecvt_name((_Locale_codecvt*)l, s); }
00055 static char const* _Loc_numeric_name(void* l, char* s)
00056 { return _Locale_numeric_name((_Locale_numeric*)l, s); }
00057 static char const* _Loc_time_name(void* l, char* s)
00058 { return _Locale_time_name((_Locale_time*)l, s); }
00059 static char const* _Loc_collate_name(void* l, char* s)
00060 { return _Locale_collate_name((_Locale_collate*)l, s); }
00061 static char const* _Loc_monetary_name(void* l, char* s)
00062 { return _Locale_monetary_name((_Locale_monetary*)l, s); }
00063 static char const* _Loc_messages_name(void* l, char* s)
00064 { return _Locale_messages_name((_Locale_messages*)l, s); }
00065 
00066 static const char* _Loc_ctype_default(char* p)
00067 { return _Locale_ctype_default(p); }
00068 static const char* _Loc_numeric_default(char * p)
00069 { return _Locale_numeric_default(p); }
00070 static const char* _Loc_time_default(char* p)
00071 { return _Locale_time_default(p); }
00072 static const char* _Loc_collate_default(char* p)
00073 { return _Locale_collate_default(p); }
00074 static const char* _Loc_monetary_default(char* p)
00075 { return _Locale_monetary_default(p); }
00076 static const char* _Loc_messages_default(char* p)
00077 { return _Locale_messages_default(p); }
00078 
00079 static void _Loc_ctype_destroy(void* p)    {_Locale_ctype_destroy((_Locale_ctype*)p); }
00080 static void _Loc_codecvt_destroy(void* p)    {_Locale_codecvt_destroy((_Locale_codecvt*)p); }
00081 static void _Loc_numeric_destroy(void* p)  {_Locale_numeric_destroy((_Locale_numeric*)p); }
00082 static void _Loc_time_destroy(void* p)     {_Locale_time_destroy((_Locale_time*)p);}
00083 static void _Loc_collate_destroy(void* p)  {_Locale_collate_destroy((_Locale_collate*)p);}
00084 static void _Loc_monetary_destroy(void* p) {_Locale_monetary_destroy((_Locale_monetary*)p);}
00085 static void _Loc_messages_destroy(void* p) {_Locale_messages_destroy((_Locale_messages*)p);}
00086 
00087 typedef void* (*loc_create_func_t)(const char *, _Locale_name_hint*, int *__err_code);
00088 typedef char const* (*loc_name_func_t)(void* l, char* s);
00089 typedef void (*loc_destroy_func_t)(void* l);
00090 typedef const char* (*loc_default_name_func_t)(char* s);
00091 typedef char const* (*loc_extract_name_func_t)(const char*, char*, _Locale_name_hint*, int *__err_code);
00092 
00093 //----------------------------------------------------------------------
00094 // Acquire and release low-level category objects.  The whole point of
00095 // this is so that we don't allocate (say) four different _Locale_ctype
00096 // objects for a single locale.
00097 
00098 // Global hash tables for category objects.
00099 typedef hash_map<string, pair<void*, size_t>, hash<string>, equal_to<string> > Category_Map;
00100 
00101 // Look up a category by name
00102 static Category_Map** ctype_hash() {
00103   static Category_Map *_S_ctype_hash = 0;
00104   return &_S_ctype_hash;
00105 }
00106 static Category_Map** codecvt_hash() {
00107   static Category_Map *_S_codecvt_hash = 0;
00108   return &_S_codecvt_hash;
00109 }
00110 static Category_Map** numeric_hash() {
00111   static Category_Map *_S_numeric_hash = 0;
00112   return &_S_numeric_hash;
00113 }
00114 static Category_Map** time_hash() {
00115   static Category_Map *_S_time_hash = 0;
00116   return &_S_time_hash;
00117 }
00118 static Category_Map** collate_hash() {
00119   static Category_Map *_S_collate_hash = 0;
00120   return &_S_collate_hash;
00121 }
00122 static Category_Map** monetary_hash() {
00123   static Category_Map *_S_monetary_hash = 0;
00124   return &_S_monetary_hash;
00125 }
00126 static Category_Map** messages_hash() {
00127   static Category_Map *_S_messages_hash;
00128   return &_S_messages_hash;
00129 }
00130 
00131 // We have a single lock for all of the hash tables.  We may wish to
00132 // replace it with six different locks.
00133 /* REFERENCED */
00134 static _STLP_STATIC_MUTEX& category_hash_mutex() {
00135   static _STLP_STATIC_MUTEX lock _STLP_MUTEX_INITIALIZER;
00136   return lock;
00137 }
00138 
00139 static void*
00140 __acquire_category(const char* &name, char *buf, _Locale_name_hint* hint,
00141                    loc_extract_name_func_t extract_name,
00142                    loc_create_func_t create_obj, loc_default_name_func_t default_name,
00143                    Category_Map ** M, int *__err_code) {
00144 #if !defined (__BORLANDC__) || (__BORLANDC__ >= 0x564)
00145   typedef Category_Map::iterator Category_iterator;
00146   pair<Category_iterator, bool> result;
00147 #else
00148 #  if !defined(_STLP_DEBUG)
00149   pair<_Ht_iterator<_Slist_iterator<pair<const string,pair<void *,unsigned int> >,_Nonconst_traits<pair<const string,pair<void *,unsigned int> > > >,_NonLocalHashMapTraitsT<pair<const string,pair<void *,unsigned int> > > >, bool> result;
00150 #  else
00151   pair<_DBG_iter<_NonDbg_hashtable<pair<const string,pair<void *,unsigned int> >,string,hash<string>,_HashMapTraitsT<pair<const string,pair<void *,unsigned int> > >,_Select1st<pair<const string,pair<void *,unsigned int> > >,_DbgEqual<string,equal_to<string> >,allocator<pair<const string,pair<void *,unsigned int> > > >,_DbgTraits<_NonLocalHashMapTraitsT<pair<const string,pair<void *,unsigned int> > > > >, bool> result;
00152 #  endif
00153 #endif
00154 
00155   *__err_code = _STLP_LOC_UNDEFINED;
00156 
00157   // Find what name to look for. Be careful if user requests the default.
00158   if (name[0] == 0) {
00159     name = default_name(buf);
00160     if (name == 0 || name[0] == 0)
00161       name = "C";
00162   }
00163   else {
00164     const char* cname = extract_name(name, buf, hint, __err_code);
00165     if (cname == 0) {
00166       return 0;
00167     }
00168     name = cname;
00169   }
00170 
00171   Category_Map::value_type __e(name, pair<void*,size_t>((void*)0,size_t(0)));
00172 
00173   _STLP_auto_lock sentry(category_hash_mutex());
00174 
00175   if (!*M)
00176     *M = new Category_Map();
00177 
00178   // Look for an existing entry with that name.
00179   result = (*M)->insert_noresize(__e);
00180 
00181   if (result.second) {
00182     // There was no entry in the map already.  Create the category.
00183     (*result.first).second.first = create_obj(name, hint, __err_code);
00184     if (!(*result.first).second.first) {
00185       (*M)->erase(result.first);
00186 #if defined (_STLP_LEAKS_PEDANTIC)
00187       if ((*M)->empty()) {
00188         delete *M;
00189         *M = 0;
00190       }
00191 #endif
00192       return 0;
00193     }
00194   }
00195 
00196   // Increment the reference count.
00197   ++((*result.first).second.second);
00198 
00199   return (*result.first).second.first;
00200 }
00201 
00202 static void
00203 __release_category(void* cat,
00204                    loc_destroy_func_t destroy_fun,
00205                    loc_name_func_t get_name,
00206                    Category_Map** M) {
00207   Category_Map *pM = *M;
00208 
00209   if (cat && pM) {
00210     // Find the name of the category object.
00211     char buf[_Locale_MAX_SIMPLE_NAME + 1];
00212     char const* name = get_name(cat, buf);
00213 
00214     if (name != 0) {
00215       _STLP_auto_lock sentry(category_hash_mutex());
00216       Category_Map::iterator it = pM->find(name);
00217       if (it != pM->end()) {
00218         // Decrement the ref count.  If it goes to zero, delete this category
00219         // from the map.
00220         if (--((*it).second.second) == 0) {
00221           void* cat1 = (*it).second.first;
00222           destroy_fun(cat1);
00223           pM->erase(it);
00224 #if defined (_STLP_LEAKS_PEDANTIC)
00225           if (pM->empty()) {
00226             delete pM;
00227             *M = 0;
00228           }
00229 #endif
00230         }
00231       }
00232     }
00233   }
00234 }
00235 
00236 _Locale_ctype* _STLP_CALL __acquire_ctype(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00237   return __REINTERPRET_CAST(_Locale_ctype*, __acquire_category(name, buf, hint,
00238                                                                _Locale_extract_ctype_name, _Loc_ctype_create, _Loc_ctype_default,
00239                                                                ctype_hash(), __err_code));
00240 }
00241 _Locale_codecvt* _STLP_CALL __acquire_codecvt(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00242   return __REINTERPRET_CAST(_Locale_codecvt*, __acquire_category(name, buf, hint,
00243                                                                  _Locale_extract_ctype_name, _Loc_codecvt_create, _Loc_ctype_default,
00244                                                                  codecvt_hash(), __err_code));
00245 }
00246 _Locale_numeric* _STLP_CALL __acquire_numeric(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00247   return __REINTERPRET_CAST(_Locale_numeric*, __acquire_category(name, buf, hint,
00248                                                                  _Locale_extract_numeric_name, _Loc_numeric_create, _Loc_numeric_default,
00249                                                                  numeric_hash(), __err_code));
00250 }
00251 _Locale_time* _STLP_CALL __acquire_time(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00252   return __REINTERPRET_CAST(_Locale_time*, __acquire_category(name, buf, hint,
00253                                                               _Locale_extract_time_name, _Loc_time_create, _Loc_time_default,
00254                                                               time_hash(), __err_code));
00255 }
00256 _Locale_collate* _STLP_CALL __acquire_collate(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00257   return __REINTERPRET_CAST(_Locale_collate*, __acquire_category(name, buf, hint,
00258                                                                  _Locale_extract_collate_name, _Loc_collate_create, _Loc_collate_default,
00259                                                                  collate_hash(), __err_code));
00260 }
00261 _Locale_monetary* _STLP_CALL __acquire_monetary(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00262   return __REINTERPRET_CAST(_Locale_monetary*, __acquire_category(name, buf, hint,
00263                                                                   _Locale_extract_monetary_name, _Loc_monetary_create, _Loc_monetary_default,
00264                                                                   monetary_hash(), __err_code));
00265 }
00266 _Locale_messages* _STLP_CALL __acquire_messages(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code) {
00267   return __REINTERPRET_CAST(_Locale_messages*, __acquire_category(name, buf, hint,
00268                                                                   _Locale_extract_messages_name, _Loc_messages_create, _Loc_messages_default,
00269                                                                   messages_hash(), __err_code));
00270 }
00271 
00272 void _STLP_CALL __release_ctype(_Locale_ctype* cat)
00273 { __release_category(cat, _Loc_ctype_destroy, _Loc_ctype_name, ctype_hash()); }
00274 void _STLP_CALL __release_codecvt(_Locale_codecvt* cat)
00275 { __release_category(cat, _Loc_codecvt_destroy, _Loc_codecvt_name, codecvt_hash()); }
00276 void _STLP_CALL __release_numeric(_Locale_numeric* cat)
00277 { __release_category(cat, _Loc_numeric_destroy, _Loc_numeric_name, numeric_hash()); }
00278 void _STLP_CALL __release_time(_Locale_time* cat)
00279 { __release_category(cat, _Loc_time_destroy, _Loc_time_name, time_hash()); }
00280 void _STLP_CALL __release_collate(_Locale_collate* cat)
00281 { __release_category(cat, _Loc_collate_destroy, _Loc_collate_name, collate_hash()); }
00282 void _STLP_CALL __release_monetary(_Locale_monetary* cat)
00283 { __release_category(cat, _Loc_monetary_destroy, _Loc_monetary_name, monetary_hash()); }
00284 void _STLP_CALL __release_messages(_Locale_messages* cat)
00285 { __release_category(cat, _Loc_messages_destroy, _Loc_messages_name, messages_hash()); }
00286 
00287 _STLP_MOVE_TO_STD_NAMESPACE
00288 _STLP_END_NAMESPACE

Generated on Sun May 27 2012 04:35:12 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.