build/stlport/src/locale.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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  */
    19 #include "stlport_prefix.h"
    21 #include <locale>
    22 #include <stdexcept>
    24 #include "c_locale.h"
    25 #include "locale_impl.h"
    27 _STLP_BEGIN_NAMESPACE
    29 #define _NAMELESS   "*"
    30 static const char _Nameless[] = _NAMELESS;
    32 static inline bool is_C_locale_name (const char* name)
    33 { return ((name[0] == 'C') && (name[1] == 0)); }
    35 locale* _Stl_get_classic_locale();
    36 locale* _Stl_get_global_locale();
    38 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) || \
    39     defined (_STLP_SIGNAL_RUNTIME_COMPATIBILITY) || defined (_STLP_CHECK_RUNTIME_COMPATIBILITY)
    40 #  define locale _STLP_NO_MEM_T_NAME(loc)
    41 #endif
    43 locale::facet::~facet() {}
    45 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES)
    46 // members that fail to be templates
    47 bool locale::operator()(const string& __x,
    48                         const string& __y) const
    49 { return __locale_do_operator_call(*this, __x, __y); }
    51 #  if !defined (_STLP_NO_WCHAR_T)
    52 bool locale::operator()(const wstring& __x,
    53                         const wstring& __y) const
    54 { return __locale_do_operator_call(*this, __x, __y); }
    55 #  endif
    56 #endif
    58 void _STLP_CALL locale::_M_throw_on_null_name()
    59 { _STLP_THROW(runtime_error("Invalid null locale name")); }
    61 void _STLP_CALL locale::_M_throw_on_combine_error(const string& name) {
    62   string what = "Unable to find facet";
    63   what += " in ";
    64   what += name.empty() ? "system" : name.c_str();
    65   what += " locale";
    66   _STLP_THROW(runtime_error(what.c_str()));
    67 }
    69 void _STLP_CALL locale::_M_throw_on_creation_failure(int __err_code,
    70                                                      const char* name, const char* facet) {
    71   string what;
    72   switch (__err_code) {
    73     case _STLP_LOC_UNSUPPORTED_FACET_CATEGORY:
    74       what = "No platform localization support for ";
    75       what += facet;
    76       what += " facet category, unable to create facet for ";
    77       what += name[0] == 0 ? "system" : name;
    78       what += " locale";
    79       break;
    80     case _STLP_LOC_NO_PLATFORM_SUPPORT:
    81       what = "No platform localization support, unable to create ";
    82       what += name[0] == 0 ? "system" : name;
    83       what += " locale";
    84       break;
    85     default:
    86     case _STLP_LOC_UNKNOWN_NAME:
    87       what = "Unable to create facet ";
    88       what += facet;
    89       what += " from name '";
    90       what += name;
    91       what += "'";
    92       break;
    93     case _STLP_LOC_NO_MEMORY:
    94       _STLP_THROW_BAD_ALLOC;
    95       break;
    96   }
    98   _STLP_THROW(runtime_error(what.c_str()));
    99 }
   101 // Takes a reference to a locale::id, assign a numeric index if not already
   102 // affected and returns it. The returned index is always positive.
   103 static const locale::id& _Stl_loc_get_index(locale::id& id) {
   104   if (id._M_index == 0) {
   105 #if defined (_STLP_ATOMIC_INCREMENT) && !defined (_STLP_WIN95_LIKE)
   106     static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max);
   107     id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index);
   108 #else
   109     static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER;
   110     _STLP_auto_lock sentry(_Index_lock);
   111     size_t new_index = locale::id::_S_max++;
   112     id._M_index = new_index;
   113 #endif
   114   }
   115   return id;
   116 }
   118 // Default constructor: create a copy of the global locale.
   119 locale::locale() _STLP_NOTHROW
   120   : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl))
   121 {}
   123 // Copy constructor
   124 locale::locale(const locale& L) _STLP_NOTHROW
   125   : _M_impl( _get_Locale_impl( L._M_impl ) )
   126 {}
   128 void locale::_M_insert(facet* f, locale::id& n) {
   129   if (f)
   130     _M_impl->insert(f, _Stl_loc_get_index(n));
   131 }
   133 locale::locale( _Locale_impl* impl ) :
   134   _M_impl( _get_Locale_impl( impl ) )
   135 {}
   137 // Create a locale from a name.
   138 locale::locale(const char* name)
   139   : _M_impl(0) {
   140   if (!name)
   141     _M_throw_on_null_name();
   143   if (is_C_locale_name(name)) {
   144     _M_impl = _get_Locale_impl( locale::classic()._M_impl );
   145     return;
   146   }
   148   _Locale_impl* impl = 0;
   149   _STLP_TRY {
   150     impl = new _Locale_impl(locale::id::_S_max, name);
   152     // Insert categories one at a time.
   153     _Locale_name_hint *hint = 0;
   154     const char* ctype_name = name;
   155     char ctype_buf[_Locale_MAX_SIMPLE_NAME];
   156     const char* numeric_name = name;
   157     char numeric_buf[_Locale_MAX_SIMPLE_NAME];
   158     const char* time_name = name;
   159     char time_buf[_Locale_MAX_SIMPLE_NAME];
   160     const char* collate_name = name;
   161     char collate_buf[_Locale_MAX_SIMPLE_NAME];
   162     const char* monetary_name = name;
   163     char monetary_buf[_Locale_MAX_SIMPLE_NAME];
   164     const char* messages_name = name;
   165     char messages_buf[_Locale_MAX_SIMPLE_NAME];
   166     hint = impl->insert_ctype_facets(ctype_name, ctype_buf, hint);
   167     hint = impl->insert_numeric_facets(numeric_name, numeric_buf, hint);
   168     hint = impl->insert_time_facets(time_name, time_buf, hint);
   169     hint = impl->insert_collate_facets(collate_name, collate_buf, hint);
   170     hint = impl->insert_monetary_facets(monetary_name, monetary_buf, hint);
   171     impl->insert_messages_facets(messages_name, messages_buf, hint);
   173     // Try to use a normalize locale name in order to have the == operator
   174     // to behave correctly:
   175     if (strcmp(ctype_name, numeric_name) == 0 &&
   176         strcmp(ctype_name, time_name) == 0 &&
   177         strcmp(ctype_name, collate_name) == 0 &&
   178         strcmp(ctype_name, monetary_name) == 0 &&
   179         strcmp(ctype_name, messages_name) == 0) {
   180       impl->name = ctype_name;
   181     }
   182     // else we keep current name.
   184     // reassign impl
   185     _M_impl = _get_Locale_impl( impl );
   186   }
   187   _STLP_UNWIND(delete impl);
   188 }
   190 static void _Stl_loc_combine_names_aux(_Locale_impl* L,
   191                                        const char* name,
   192                                        const char* ctype_name, const char* time_name, const char* numeric_name,
   193                                        const char* collate_name, const char* monetary_name, const char* messages_name,
   194                                        locale::category c) {
   195   // This function is only called when names has been validated so using _Locale_extract_*_name
   196   // can't fail.
   197   int __err_code;
   198   char buf[_Locale_MAX_SIMPLE_NAME];
   199   L->name = string("LC_CTYPE=") + _Locale_extract_ctype_name((c & locale::ctype) ? ctype_name : name, buf, 0, &__err_code) + ";";
   200   L->name += string("LC_TIME=") + _Locale_extract_time_name((c & locale::time) ? time_name : name, buf, 0, &__err_code) + ";";
   201   L->name += string("LC_NUMERIC=") + _Locale_extract_numeric_name((c & locale::numeric) ? numeric_name : name, buf, 0, &__err_code) + ";";
   202   L->name += string("LC_COLLATE=") + _Locale_extract_collate_name((c & locale::collate) ? collate_name : name, buf, 0, &__err_code) + ";";
   203   L->name += string("LC_MONETARY=") + _Locale_extract_monetary_name((c & locale::monetary) ? monetary_name : name, buf, 0, &__err_code) + ";";
   204   L->name += string("LC_MESSAGES=") + _Locale_extract_messages_name((c & locale::messages) ? messages_name : name, buf, 0, &__err_code);
   205 }
   207 // Give L a name where all facets except those in category c
   208 // are taken from name1, and those in category c are taken from name2.
   209 static void _Stl_loc_combine_names(_Locale_impl* L,
   210                                    const char* name1, const char* name2,
   211                                    locale::category c) {
   212   if ((c & locale::all) == 0 || strcmp(name1, name1) == 0)
   213     L->name = name1;
   214   else if ((c & locale::all) == locale::all)
   215     L->name = name2;
   216   else {
   217     _Stl_loc_combine_names_aux(L, name1, name2, name2, name2, name2, name2, name2, c);
   218   }
   219 }
   221 static void _Stl_loc_combine_names(_Locale_impl* L,
   222                                    const char* name,
   223                                    const char* ctype_name, const char* time_name, const char* numeric_name,
   224                                    const char* collate_name, const char* monetary_name, const char* messages_name,
   225                                    locale::category c) {
   226   if ((c & locale::all) == 0 || (strcmp(name, ctype_name) == 0 &&
   227                                  strcmp(name, time_name) == 0 &&
   228                                  strcmp(name, numeric_name) == 0 &&
   229                                  strcmp(name, collate_name) == 0 &&
   230                                  strcmp(name, monetary_name) == 0 &&
   231                                  strcmp(name, messages_name) == 0))
   232     L->name = name;
   233   else if ((c & locale::all) == locale::all && strcmp(ctype_name, time_name) == 0 &&
   234                                                strcmp(ctype_name, numeric_name) == 0 &&
   235                                                strcmp(ctype_name, collate_name) == 0 &&
   236                                                strcmp(ctype_name, monetary_name) == 0 &&
   237                                                strcmp(ctype_name, messages_name) == 0)
   238     L->name = ctype_name;
   239   else {
   240     _Stl_loc_combine_names_aux(L, name, ctype_name, time_name, numeric_name, collate_name, monetary_name, messages_name, c);
   241   }
   242 }
   245 // Create a locale that's a copy of L, except that all of the facets
   246 // in category c are instead constructed by name.
   247 locale::locale(const locale& L, const char* name, locale::category c)
   248   : _M_impl(0) {
   249   if (!name)
   250     _M_throw_on_null_name();
   252   if (!::strcmp(_Nameless, name))
   253     _STLP_THROW(runtime_error("Invalid locale name '" _NAMELESS "'"));
   255   _Locale_impl* impl = 0;
   257   _STLP_TRY {
   258     impl = new _Locale_impl(*L._M_impl);
   260     _Locale_name_hint *hint = 0;
   261     const char* ctype_name = name;
   262     char ctype_buf[_Locale_MAX_SIMPLE_NAME];
   263     const char* numeric_name = name;
   264     char numeric_buf[_Locale_MAX_SIMPLE_NAME];
   265     const char* time_name = name;
   266     char time_buf[_Locale_MAX_SIMPLE_NAME];
   267     const char* collate_name = name;
   268     char collate_buf[_Locale_MAX_SIMPLE_NAME];
   269     const char* monetary_name = name;
   270     char monetary_buf[_Locale_MAX_SIMPLE_NAME];
   271     const char* messages_name = name;
   272     char messages_buf[_Locale_MAX_SIMPLE_NAME];
   273     if (c & locale::ctype)
   274       hint = impl->insert_ctype_facets(ctype_name, ctype_buf, hint);
   275     if (c & locale::numeric)
   276       hint = impl->insert_numeric_facets(numeric_name, numeric_buf, hint);
   277     if (c & locale::time)
   278       hint = impl->insert_time_facets(time_name, time_buf, hint);
   279     if (c & locale::collate)
   280       hint = impl->insert_collate_facets(collate_name, collate_buf, hint);
   281     if (c & locale::monetary)
   282       hint = impl->insert_monetary_facets(monetary_name, monetary_buf,hint);
   283     if (c & locale::messages)
   284       impl->insert_messages_facets(messages_name, messages_buf, hint);
   286     _Stl_loc_combine_names(impl, L._M_impl->name.c_str(),
   287                            ctype_name, time_name, numeric_name,
   288                            collate_name, monetary_name, messages_name, c);
   289     _M_impl = _get_Locale_impl( impl );
   290   }
   291   _STLP_UNWIND(delete impl)
   292 }
   294 // Contruct a new locale where all facets that aren't in category c
   295 // come from L1, and all those that are in category c come from L2.
   296 locale::locale(const locale& L1, const locale& L2, category c)
   297   : _M_impl(0) {
   298   _Locale_impl* impl = new _Locale_impl(*L1._M_impl);
   300   _Locale_impl* i2 = L2._M_impl;
   302   if (L1.name() != _Nameless && L2.name() != _Nameless)
   303     _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c);
   304   else {
   305     impl->name = _Nameless;
   306   }
   308   if (c & collate) {
   309     impl->insert( i2, _STLP_STD::collate<char>::id);
   310 # ifndef _STLP_NO_WCHAR_T
   311     impl->insert( i2, _STLP_STD::collate<wchar_t>::id);
   312 # endif
   313   }
   314   if (c & ctype) {
   315     impl->insert( i2, _STLP_STD::ctype<char>::id);
   316     impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id);
   317 # ifndef _STLP_NO_WCHAR_T
   318     impl->insert( i2, _STLP_STD::ctype<wchar_t>::id);
   319     impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id);
   320 # endif
   321   }
   322   if (c & monetary) {
   323     impl->insert( i2, _STLP_STD::moneypunct<char, true>::id);
   324     impl->insert( i2, _STLP_STD::moneypunct<char, false>::id);
   325     impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
   326     impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
   327 # ifndef _STLP_NO_WCHAR_T
   328     impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id);
   329     impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id);
   330     impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
   331     impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
   332 # endif
   333   }
   334   if (c & numeric) {
   335     impl->insert( i2, _STLP_STD::numpunct<char>::id);
   336     impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
   337     impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
   338 # ifndef _STLP_NO_WCHAR_T
   339     impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id);
   340     impl->insert( i2, _STLP_STD::num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
   341     impl->insert( i2, _STLP_STD::num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
   342 # endif
   343   }
   344   if (c & time) {
   345     impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
   346     impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
   347 # ifndef _STLP_NO_WCHAR_T
   348     impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
   349     impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
   350 # endif
   351   }
   352   if (c & messages) {
   353     impl->insert( i2, _STLP_STD::messages<char>::id);
   354 # ifndef _STLP_NO_WCHAR_T
   355     impl->insert( i2, _STLP_STD::messages<wchar_t>::id);
   356 # endif
   357   }
   358   _M_impl = _get_Locale_impl( impl );
   359 }
   361 // Destructor.
   362 locale::~locale() _STLP_NOTHROW {
   363   if (_M_impl)
   364     _release_Locale_impl(_M_impl);
   365 }
   367 // Assignment operator.  Much like the copy constructor: just a bit of
   368 // pointer twiddling.
   369 const locale& locale::operator=(const locale& L) _STLP_NOTHROW {
   370   if (this->_M_impl != L._M_impl) {
   371     if (this->_M_impl)
   372       _release_Locale_impl(this->_M_impl);
   373     this->_M_impl = _get_Locale_impl(L._M_impl);
   374   }
   375   return *this;
   376 }
   378 locale::facet* locale::_M_get_facet(const locale::id& n) const {
   379   return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0;
   380 }
   382 locale::facet* locale::_M_use_facet(const locale::id& n) const {
   383   locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0);
   384   if (!f)
   385     _M_impl->_M_throw_bad_cast();
   386   return f;
   387 }
   389 string locale::name() const {
   390   return _M_impl->name;
   391 }
   393 // Compare two locales for equality.
   394 bool locale::operator==(const locale& L) const {
   395   return this->_M_impl == L._M_impl ||
   396          (this->name() == L.name() && this->name() != _Nameless);
   397 }
   399 bool locale::operator!=(const locale& L) const {
   400   return !(*this == L);
   401 }
   403 // static data members.
   405 const locale& _STLP_CALL locale::classic() {
   406   return *_Stl_get_classic_locale();
   407 }
   409 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
   410 locale _STLP_CALL locale::global(const locale& L) {
   411 #else
   412 _Locale_impl* _STLP_CALL locale::global(const locale& L) {
   413 #endif
   414   locale old(_Stl_get_global_locale()->_M_impl);
   415   if (_Stl_get_global_locale()->_M_impl != L._M_impl) {
   416     _release_Locale_impl(_Stl_get_global_locale()->_M_impl);
   417     // this assign should be atomic, should be fixed here:
   418     _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl);
   420     // Set the global C locale, if appropriate.
   421 #if !defined(_STLP_NO_LOCALE_SUPPORT)
   422     if (L.name() != _Nameless)
   423       setlocale(LC_ALL, L.name().c_str());
   424 #endif
   425   }
   427 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
   428   return old;
   429 #else
   430   return old._M_impl;
   431 #endif
   432 }
   434 #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
   435 const locale::category locale::none;
   436 const locale::category locale::collate;
   437 const locale::category locale::ctype;
   438 const locale::category locale::monetary;
   439 const locale::category locale::numeric;
   440 const locale::category locale::time;
   441 const locale::category locale::messages;
   442 const locale::category locale::all;
   443 #endif
   445 _STLP_END_NAMESPACE

mercurial