os/ossrv/genericopenlibs/cppstdlib/stl/src/locale_catalog.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
     3  *
     4  * Copyright (c) 1999
     5  * Silicon Graphics Computer Systems, Inc.
     6  *
     7  * Copyright (c) 1999
     8  * Boris Fomitchev
     9  *
    10  * This material is provided "as is", with absolutely no warranty expressed
    11  * or implied. Any use is at your own risk.
    12  *
    13  * Permission to use or copy this software for any purpose is hereby granted
    14  * without fee, provided the above notices are retained on all copies.
    15  * Permission to modify the code and to distribute modified code is granted,
    16  * provided the above notices are retained, and a notice that the code was
    17  * modified is included with the above copyright notice.
    18  *
    19  */
    20 #include "stlport_prefix.h"
    21 
    22 #include <hash_map>
    23 #include <string>
    24 
    25 #include <locale>
    26 #include <istream>
    27 
    28 #include "c_locale.h"
    29 #include "locale_impl.h"
    30 #include "acquire_release.h"
    31 
    32 #if defined(__SYMBIAN32__WSD__)
    33 #include "libstdcppwsd.h"
    34 #endif
    35 
    36 _STLP_BEGIN_NAMESPACE
    37 _STLP_MOVE_TO_PRIV_NAMESPACE
    38 
    39 // those wrappers are needed to avoid extern "C"
    40 
    41 static void* _Loc_ctype_create(const char * s, _Locale_name_hint* hint)
    42 { return _Locale_ctype_create(s, hint); }
    43 static void* _Loc_numeric_create(const char * s, _Locale_name_hint* hint)
    44 { return _Locale_numeric_create(s, hint); }
    45 static void* _Loc_time_create(const char * s, _Locale_name_hint* hint)
    46 { return _Locale_time_create(s, hint); }
    47 static void* _Loc_collate_create(const char * s, _Locale_name_hint* hint)
    48 { return _Locale_collate_create(s, hint); }
    49 static void* _Loc_monetary_create(const char * s, _Locale_name_hint* hint)
    50 { return _Locale_monetary_create(s, hint); }
    51 static void* _Loc_messages_create(const char * s, _Locale_name_hint* hint)
    52 { return _Locale_messages_create(s, hint); }
    53 
    54 static char const* _Loc_ctype_name(const void* l, char* s)
    55 { return _Locale_ctype_name(l, s); }
    56 static char const* _Loc_numeric_name(const void* l, char* s)
    57 { return _Locale_numeric_name(l, s); }
    58 static char const* _Loc_time_name(const void* l, char* s)
    59 { return _Locale_time_name(l,s); }
    60 static char const* _Loc_collate_name( const void* l, char* s)
    61 { return _Locale_collate_name(l,s); }
    62 static char const* _Loc_monetary_name(const void* l, char* s)
    63 { return _Locale_monetary_name(l,s); }
    64 static char const* _Loc_messages_name(const void* l, char* s)
    65 { return _Locale_messages_name(l,s); }
    66 
    67 static const char* _Loc_ctype_default(char* p)
    68 { return _Locale_ctype_default(p); }
    69 static const char* _Loc_numeric_default(char * p)
    70 { return _Locale_numeric_default(p); }
    71 static const char* _Loc_time_default(char* p)
    72 { return _Locale_time_default(p); }
    73 static const char* _Loc_collate_default(char* p)
    74 { return _Locale_collate_default(p); }
    75 static const char* _Loc_monetary_default(char* p)
    76 { return _Locale_monetary_default(p); }
    77 static const char* _Loc_messages_default(char* p)
    78 { return _Locale_messages_default(p); }
    79 
    80 static void _Loc_ctype_destroy(void* p)    {_Locale_ctype_destroy(p); }
    81 static void _Loc_numeric_destroy(void* p)  {_Locale_numeric_destroy(p); }
    82 static void _Loc_time_destroy(void* p)     {_Locale_time_destroy(p);}
    83 static void _Loc_collate_destroy(void* p)  {_Locale_collate_destroy(p);}
    84 static void _Loc_monetary_destroy(void* p) {_Locale_monetary_destroy(p);}
    85 static void _Loc_messages_destroy(void* p) {_Locale_messages_destroy(p);}
    86 
    87 typedef void* (*loc_create_func_t)(const char *, _Locale_name_hint*);
    88 typedef char const* (*loc_name_func_t)(const void* l, char* s);
    89 typedef void (*loc_destroy_func_t)(void* l);
    90 typedef const char* (*loc_default_name_func_t)(char* s);
    91 typedef char const* (*loc_extract_name_func_t)(const char*, char*, _Locale_name_hint*);
    92 
    93 //----------------------------------------------------------------------
    94 // Acquire and release low-level category objects.  The whole point of
    95 // this is so that we don't allocate (say) four different _Locale_ctype
    96 // objects for a single locale.
    97 
    98 // Global hash tables for category objects.
    99 typedef hash_map<string, pair<void*, size_t>, hash<string>, equal_to<string> > Category_Map;
   100 
   101 # if !defined(__SYMBIAN32__WSD__)
   102 // Look up a category by name
   103 static Category_Map** ctype_hash() {
   104   static Category_Map *_S_ctype_hash = 0;
   105   return &_S_ctype_hash;
   106 }
   107 static Category_Map** numeric_hash() {
   108   static Category_Map *_S_numeric_hash = 0;
   109   return &_S_numeric_hash;
   110 }
   111 static Category_Map** time_hash() {
   112   static Category_Map *_S_time_hash = 0;
   113   return &_S_time_hash;
   114 }
   115 static Category_Map** collate_hash() {
   116   static Category_Map *_S_collate_hash = 0;
   117   return &_S_collate_hash;
   118 }
   119 static Category_Map** monetary_hash() {
   120   static Category_Map *_S_monetary_hash = 0;
   121   return &_S_monetary_hash;
   122 }
   123 static Category_Map** messages_hash() {
   124   static Category_Map *_S_messages_hash;
   125   return &_S_messages_hash;
   126 }
   127 #else
   128 // Look up a category by name
   129 static Category_Map** ctype_hash() {
   130   return &get_libcpp_wsd()._S_ctype_hash;
   131 }
   132 static Category_Map** numeric_hash() {
   133   return &get_libcpp_wsd()._S_numeric_hash;
   134 }
   135 static Category_Map** time_hash() {
   136   return &get_libcpp_wsd()._S_time_hash;
   137 }
   138 static Category_Map** collate_hash() {
   139   return &get_libcpp_wsd()._S_collate_hash;
   140 }
   141 static Category_Map** monetary_hash() {
   142   return &get_libcpp_wsd()._S_monetary_hash;
   143 }
   144 static Category_Map** messages_hash() {
   145   return &get_libcpp_wsd()._S_messages_hash;
   146 }
   147 
   148 void Category_Map_Init()
   149 {
   150 	get_libcpp_wsd()._S_ctype_hash = 0;
   151 	get_libcpp_wsd()._S_numeric_hash = 0;
   152 	get_libcpp_wsd()._S_time_hash = 0;
   153 	get_libcpp_wsd()._S_collate_hash = 0;
   154 	get_libcpp_wsd()._S_monetary_hash = 0;
   155 	get_libcpp_wsd()._S_messages_hash = 0;
   156 }
   157 # endif
   158 
   159 
   160 // We have a single lock for all of the hash tables.  We may wish to
   161 // replace it with six different locks.
   162 /* REFERENCED */
   163 # if !defined(__SYMBIAN32__WSD__)
   164 static _STLP_STATIC_MUTEX __category_hash_lock _STLP_MUTEX_INITIALIZER;
   165 #else
   166 
   167 #define __category_hash_lock	   get_locale_catalog_category_hash_lock()
   168 
   169 void locale_catalog_category_hash_lock_init()
   170 {
   171 	__category_hash_lock._M_lock.iState   = _ENeedsNormalInit;
   172 	__category_hash_lock._M_lock.iPtr     = 0;
   173 	__category_hash_lock._M_lock.iReentry = 0;
   174 }
   175 # endif
   176 
   177 
   178 static void*
   179 __acquire_category(const char* name, _Locale_name_hint* hint,
   180                    loc_extract_name_func_t extract_name,
   181                    loc_create_func_t create_obj, loc_default_name_func_t default_obj,
   182                    Category_Map ** M) {
   183 #if !defined (__BORLANDC__) || (__BORLANDC__ >= 0x564)
   184   typedef Category_Map::iterator Category_iterator;
   185   pair<Category_iterator, bool> result;
   186 #else
   187   pair<Category_Map::iterator, bool> result;
   188 #endif
   189 
   190   // Find what name to look for. Be careful if user requests the default.
   191   const char *cname;
   192   char buf[_Locale_MAX_SIMPLE_NAME];
   193   if (name == 0 || name[0] == 0) {
   194     cname = default_obj(buf);
   195     if (cname == 0 || cname[0] == 0)
   196       cname = "C";
   197   }
   198   else {
   199     cname = extract_name(name, buf, hint);
   200     if (cname == 0) {
   201       return 0;
   202     }
   203   }
   204 
   205   Category_Map::value_type __e(cname, pair<void*,size_t>((void*)0,size_t(0)));
   206 
   207   _STLP_auto_lock sentry(__category_hash_lock);
   208 
   209   if (!*M)
   210     *M = new Category_Map();
   211 
   212 #if defined(__SC__)    //*TY 06/01/2000 - added workaround for SCpp
   213   if(!*M) delete *M;  //*TY 06/01/2000 - it forgets to generate dtor for Category_Map class. This fake code forces to generate one.
   214 #endif          //*TY 06/01/2000 -
   215 
   216   // Look for an existing entry with that name.
   217   result = (*M)->insert_noresize(__e);
   218 
   219   // There was no entry in the map already.  Create the category.
   220   if (result.second)
   221     (*result.first).second.first = create_obj(cname, hint);
   222 
   223   // Increment the reference count.
   224   ++((*result.first).second.second);
   225 
   226   return (*result.first).second.first;
   227 }
   228 
   229 static void
   230 __release_category(void* cat,
   231                    loc_destroy_func_t destroy_fun,
   232                    loc_name_func_t get_name,
   233                    Category_Map** M) {
   234   Category_Map *pM = *M;
   235 
   236   if (cat && pM) {
   237     // Find the name of the category object.
   238     char buf[_Locale_MAX_SIMPLE_NAME + 1];
   239     char const* name = get_name(cat, buf);
   240 
   241     if (name != 0) {
   242       _STLP_auto_lock sentry(__category_hash_lock);
   243       Category_Map::iterator it = pM->find(name);
   244       if (it != pM->end()) {
   245         // Decrement the ref count.  If it goes to zero, delete this category
   246         // from the map.
   247         if (--((*it).second.second) == 0) {
   248           void* cat1 = (*it).second.first;
   249           destroy_fun(cat1);
   250           pM->erase(it);
   251 #if defined (_STLP_LEAKS_PEDANTIC)
   252           if (pM->empty()) {
   253             delete pM;
   254             *M = 0;
   255           }
   256 #endif /* _STLP_LEAKS_PEDANTIC */
   257         }
   258       }
   259     }
   260   }
   261 }
   262 
   263 _Locale_ctype* _STLP_CALL __acquire_ctype(const char* name, _Locale_name_hint* hint) {
   264   return __REINTERPRET_CAST(_Locale_ctype*, __acquire_category(name, hint,
   265                                                                _Locale_extract_ctype_name, _Loc_ctype_create, _Loc_ctype_default,
   266                                                                ctype_hash()));
   267 }
   268 _Locale_numeric* _STLP_CALL __acquire_numeric(const char* name, _Locale_name_hint* hint) {
   269   return __REINTERPRET_CAST(_Locale_numeric*, __acquire_category(name, hint,
   270                                                                  _Locale_extract_numeric_name, _Loc_numeric_create, _Loc_numeric_default,
   271                                                                  numeric_hash()));
   272 }
   273 _STLP_DECLSPEC _Locale_time* _STLP_CALL __acquire_time(const char* name, _Locale_name_hint* hint) {
   274   return __REINTERPRET_CAST(_Locale_time*, __acquire_category(name, hint,
   275                                                               _Locale_extract_time_name, _Loc_time_create, _Loc_time_default,
   276                                                               time_hash()));
   277 }
   278 _Locale_collate* _STLP_CALL __acquire_collate(const char* name, _Locale_name_hint* hint) {
   279   return __REINTERPRET_CAST(_Locale_collate*, __acquire_category(name, hint,
   280                                                                  _Locale_extract_collate_name, _Loc_collate_create, _Loc_collate_default,
   281                                                                  collate_hash()));
   282 }
   283 _Locale_monetary* _STLP_CALL __acquire_monetary(const char* name, _Locale_name_hint* hint) {
   284   return __REINTERPRET_CAST(_Locale_monetary*, __acquire_category(name, hint,
   285                                                                   _Locale_extract_monetary_name, _Loc_monetary_create, _Loc_monetary_default,
   286                                                                   monetary_hash()));
   287 }
   288 _Locale_messages* _STLP_CALL __acquire_messages(const char* name, _Locale_name_hint* hint) {
   289   return __REINTERPRET_CAST(_Locale_messages*, __acquire_category(name, hint,
   290                                                                   _Locale_extract_messages_name, _Loc_messages_create, _Loc_messages_default,
   291                                                                   messages_hash()));
   292 }
   293 
   294 void _STLP_CALL __release_ctype(_Locale_ctype* cat)
   295 { __release_category(cat, _Loc_ctype_destroy, _Loc_ctype_name, ctype_hash()); }
   296 void _STLP_CALL __release_numeric(_Locale_numeric* cat)
   297 { __release_category(cat, _Loc_numeric_destroy, _Loc_numeric_name, numeric_hash()); }
   298 _STLP_DECLSPEC void _STLP_CALL __release_time(_Locale_time* cat)
   299 { __release_category(cat, _Loc_time_destroy, _Loc_time_name, time_hash()); }
   300 void _STLP_CALL __release_collate(_Locale_collate* cat)
   301 { __release_category(cat, _Loc_collate_destroy, _Loc_collate_name, collate_hash()); }
   302 void _STLP_CALL __release_monetary(_Locale_monetary* cat)
   303 { __release_category(cat, _Loc_monetary_destroy, _Loc_monetary_name, monetary_hash()); }
   304 void _STLP_CALL __release_messages(_Locale_messages* cat)
   305 { __release_category(cat, _Loc_messages_destroy, _Loc_messages_name, messages_hash()); }
   306 
   307 _STLP_MOVE_TO_STD_NAMESPACE
   308 _STLP_END_NAMESPACE