56int __rw_get_cat (
int);
60const char* __rw_get_cat_name (
int category)
68 { _RWSTD_LC_COLLATE,
"LC_COLLATE"},
69 { _RWSTD_LC_CTYPE,
"LC_CTYPE"},
70 { _RWSTD_LC_MONETARY,
"LC_MONETARY"},
71 { _RWSTD_LC_NUMERIC,
"LC_NUMERIC"},
72 { _RWSTD_LC_TIME,
"LC_TIME"}
74#ifdef _RWSTD_LC_MESSAGES
75 , { _RWSTD_LC_MESSAGES,
"LC_MESSAGES" }
80 for (_RWSTD_SIZE_T
i = 0;
i !=
sizeof cats /
sizeof *cats; ++
i) {
81 if (category == cats [
i].cat)
89int __rw_facet::_C_opts = 0
91#ifndef _RWSTD_NO_INITIAL_CAT_SEP
92 | __rw_facet::_C_prepend_cat_sep
95#ifndef _RWSTD_NO_CAT_NAMES
96 | __rw_facet::_C_use_cat_names
99#ifndef _RWSTD_NO_CONDENSED_NAME
100 | __rw_facet::_C_condensed_name
107__rw_facet::__rw_facet (_RWSTD_SIZE_T __ref )
108 : _C_name (0), _C_buf (0), _C_impdata (0), _C_impsize (0),
109 _C_type (_C_unknown), _C_ref (__ref), _C_pid (0 )
114__rw_facet::~__rw_facet ()
118 static const char destroyed[] =
"*** destroyed facet ***";
125 _C_type = _C_invalid;
127 if (_C_name != _C_buf)
138 if ((_RWSTD_SIZE_T)(-1) == _C_impsize)
140 else if (_C_impdata && _C_impsize)
141 __rw_release_facet_data (_C_impdata, _C_impsize);
145void __rw_facet::_C_set_name (
const char *
name,
char *
buf, _RWSTD_SIZE_T
size)
154 _RWSTD_SIZE_T
len = ::strlen (
name) + 1;
164const void* __rw_facet::_C_get_data ()
185 __rw_chararray locname (_C_name && _C_name [0] ? _C_name :
"C");
188 const void* pdata = 0;
189 _RWSTD_SIZE_T
sz = 0;
192 const int cat = __rw_get_cat (
int (*_C_pid));
198 const bool is_wcodecvt_byname =
199 _C_wcodecvt_byname == __rw_locale::_C_get_facet_type (*
this);
203 pdata = __rw_get_facet_data (cat,
sz, locname.data ());
209 _RW::__rw_chararray strip_name;
211 const char* pstr = strstr (locname.data (),
"@UCS");
212 const size_t plen = size_t (pstr - locname.data ());
214 if (pstr && !pstr [4]) {
217 strip_name.append (locname.data (), plen);
218 pdata = __rw_get_facet_data (cat,
sz, strip_name.data ());
220 else if ( pstr && pstr [4] ==
'-' && !pstr [6]
221 && (
'4' == pstr [5] &&
sizeof (
wchar_t) == 4
222 ||
'2' == pstr [5] &&
sizeof (
wchar_t) == 2)) {
227 strip_name.append (locname.data (), plen);
228 pdata = __rw_get_facet_data (cat,
sz, strip_name.data ());
233 if (!pdata && is_wcodecvt_byname) {
235 pstr = pstr ? strip_name.data () : locname.data ();
236 pdata = __rw_get_facet_data (cat,
sz, 0, pstr );
248 _C_impsize = (_RWSTD_SIZE_T)-1;
252 if (!is_wcodecvt_byname || pstr && pdata) {
258 else if (!is_wcodecvt_byname) {
266 const _RW::__rw_ctype_t* pctype =
275 __rw_chararray codeset_fname;
276 const char* codeset = pctype->codeset_name ();
280 const size_t dirlen = size_t (slash - locname.data ()) + 1;
282 codeset_fname.assign (locname.data (), dirlen);
283 codeset_fname.append (codeset);
284 codeset = codeset_fname.data ();
288 _C_impdata = __rw_get_facet_data (cat, _C_impsize, 0, codeset);
291 __rw_munmap (pdata,
sz);
300static int cmpfacets (
const void *pv1,
const void *pv2)
305 const __rw_facet*
const pf1 =
307 const __rw_facet*
const pf2 =
310 if (__rw_access::_C_get_type(*pf1) == __rw_access::_C_get_type(*pf2)) {
311 return ::strcmp (__rw_access::_C_get_name(*pf1) ?
312 __rw_access::_C_get_name(*pf1) :
"C",
313 __rw_access::_C_get_name(*pf2) ?
314 __rw_access::_C_get_name(*pf2) :
"C");
317 return __rw_access::_C_get_type(*pf2) - __rw_access::_C_get_type(*pf1);
321struct __rw_facet_info
324 __rw_facet::_C_facet_type _C_type;
328static int cmpfacet (
const void *pv1,
const void *pv2)
333 const __rw_facet_info*
const pinfo =
336 const __rw_facet*
const pfacet =
339 if (pinfo->_C_type == __rw_access::_C_get_type(*pfacet)) {
340 return ::strcmp (pinfo->_C_name ? pinfo->_C_name :
"C",
341 __rw_access::_C_get_name(*pfacet) ?
342 __rw_access::_C_get_name(*pfacet) :
"C");
345 return __rw_access::_C_get_type(*pfacet) - pinfo->_C_type;
352__rw_facet::_C_manage (__rw_facet *pfacet,
355 __rw_facet::_C_ctor_t *ctor)
359 static __rw_facet* std_facet_buf [__rw_facet::_C_last_type * 8];
360 static __rw_facet** std_facets = std_facet_buf;
361 static _RWSTD_SIZE_T n_std_facets = 0;
362 static _RWSTD_SIZE_T std_facet_bufsize =
363 sizeof std_facet_buf /
sizeof *std_facet_buf;
374 name = __rw_locale::_C_get_cat_name (*pfacet);
380 ::bsearch (&pfacet, std_facets, n_std_facets,
381 sizeof pfacet, &cmpfacets);
384 const _RWSTD_SIZE_T
inx =
388 pfacet = std_facets [
inx];
390 if (0 == __rw_locale::_C_remove_ref (*pfacet)) {
392 static const _RWSTD_SIZE_T bufsize =
393 sizeof std_facet_buf /
sizeof *std_facet_buf;
397 if (n_std_facets < bufsize / 2 && std_facets != std_facet_buf) {
405 ::memcpy (std_facet_buf, std_facets,
406 inx *
sizeof (*std_facets));
408 ::memcpy (std_facet_buf +
inx,
409 std_facets +
inx + 1,
411 *
sizeof (*std_facets));
414 std_facets = std_facet_buf;
419 ::memmove (std_facets +
inx,
420 std_facets +
inx + 1,
422 *
sizeof (*std_facets));
434 const _RWSTD_SIZE_T ref = __rw_locale::_C_remove_ref (*pfacet);
445 const __rw_facet_info info = {
name, type };
447 const void *pcf = ::bsearch (&info, std_facets, n_std_facets,
448 sizeof pfacet, &cmpfacet);
458 __rw_locale::_C_add_ref (*pfacet);
462 if (n_std_facets == std_facet_bufsize) {
465 __rw_facet **
tmp =
new __rw_facet* [n_std_facets * 2];
467 ::memcpy (
tmp, std_facets, n_std_facets *
sizeof *
tmp);
469 if (std_facets != std_facet_buf)
473 std_facet_bufsize *= 2;
482 pfacet = ctor (1, type & 1 ? 0 :
name);
487 *__rw_access::_C_get_pid (*pfacet) =
490 if (__rw_access::_C_get_type (*pfacet) != type) {
492 __rw_access::_C_get_type (*pfacet) = type;
495 if (__rw_access::_C_get_ref (*pfacet) != 1) {
504 __rw_access::_C_get_ref (*pfacet) = 1;
508 std_facets [n_std_facets++] = pfacet;
511 ::qsort (std_facets, n_std_facets,
sizeof pfacet, &cmpfacets);
520const void* __rw_get_facet_data (
int cat, _RWSTD_SIZE_T &impsize,
521 const char*
name,
const char* encoding)
523 if (__rw_facet::_C_use_libc == (__rw_facet::_C_opts &
524 (__rw_facet::_C_use_libc |
525 __rw_facet::_C_use_libstd))) {
530 __rw_chararray pathname;
534 const char *locname =
name ?
name :
"C";
536 if (
'/' == *locname) {
542#ifndef _RWSTD_LOCALE_ROOT_ENVVAR
543# define _RWSTD_LOCALE_ROOT_ENVVAR "RWSTD_LOCALE_ROOT"
554 pathname.append (root);
555 if (pathname.data () [pathname.size () - 1] !=
'/')
556 pathname.append (
"/", 1);
568 pathname.append (locname).append (
"/", 1);
569 db = __rw_get_cat_name (cat);
576 pathname.append (db);
577 path = pathname.data ();
581 return __rw_mmap (
path, &impsize);
585void __rw_release_facet_data (
const void* pv, _RWSTD_SIZE_T
sz)
587 __rw_munmap (pv,
sz);
596static _RWSTD_SIZE_T __rw_id_gen = __rw_facet::_C_last_type + 1;
599_RWSTD_SIZE_T __rw_facet_id::_C_init ()
const
610 const _RWSTD_SIZE_T new_id =
613#ifndef _RWSTD_NO_MUTABLE
#define _RWSTD_ATOMIC_PREINCREMENT(x, ignore)
#define _RWSTD_UNUSED(arg)
#define _RWSTD_STATIC_CAST(T, x)
#define _RWSTD_NAMESPACE(name)
#define _RWSTD_MT_GUARD(ignore)
#define _RWSTD_ASSERT(ignore)
#define _RWSTD_CONST_CAST(T, x)
#define _RWSTD_MT_STATIC_GUARD(name)
#define _RWSTD_LOCALE_ROOT_ENVVAR