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