Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.2 KiB

  1. // locale0 -- class locale basic member functions
  2. #include <climits>
  3. #include <locale>
  4. #include <xdebug>
  5. struct _Fac_node
  6. { // node for lazy facet recording
  7. _Fac_node(_Fac_node *_Nextarg, std::locale::facet *_Facptrarg)
  8. : _Next(_Nextarg), _Facptr(_Facptrarg)
  9. { // construct a node with value
  10. }
  11. ~_Fac_node()
  12. { // destroy a facet
  13. _DELETE_CRT(_Facptr->_Decref());
  14. }
  15. _Fac_node *_Next;
  16. std::locale::facet *_Facptr;
  17. };
  18. static _Fac_node *_Fac_head = 0;
  19. _C_STD_BEGIN
  20. _EXTERN_C
  21. void __cdecl _Fac_tidy()
  22. { // destroy lazy facets
  23. std::_Lockit lock(_LOCK_LOCALE); // prevent double delete
  24. for (; _Fac_head != 0; )
  25. { // destroy a lazy facet node
  26. _Fac_node *nodeptr = _Fac_head;
  27. _Fac_head = nodeptr->_Next;
  28. _DELETE_CRT(nodeptr);
  29. }
  30. }
  31. void __cdecl _Deletegloballocale(void *ptr)
  32. { // delete a global locale reference
  33. std::locale::_Locimp *locptr = *(std::locale::_Locimp **)ptr;
  34. if (locptr != 0)
  35. _DELETE_CRT(locptr->_Decref());
  36. }
  37. static std::locale::_Locimp *global_locale = 0; // pointer to current locale
  38. static void __cdecl tidy_global()
  39. { // delete static global locale reference
  40. std::_Lockit lock(_LOCK_LOCALE); // prevent double delete
  41. _Deletegloballocale(&global_locale);
  42. }
  43. std::locale::_Locimp *__cdecl _Getgloballocale()
  44. { // return pointer to current locale
  45. return (global_locale);
  46. }
  47. void __cdecl _Setgloballocale(void *ptr)
  48. { // alter pointer to current locale
  49. static bool registered = false;
  50. if (!registered)
  51. { // register cleanup first time
  52. registered = true;
  53. ::_Atexit(&tidy_global);
  54. }
  55. global_locale = (std::locale::_Locimp *)ptr;
  56. }
  57. _END_EXTERN_C
  58. _C_STD_END
  59. _STD_BEGIN
  60. #pragma warning(disable: 4786)
  61. static locale classic_locale(_Noinit); // "C" locale object, uninitialized
  62. locale::_Locimp *locale::_Locimp::_Clocptr = 0; // pointer to classic_locale
  63. int locale::id::_Id_cnt = 0; // unique id counter for facets
  64. _TEMPLATE_STAT locale::id ctype<char>::id;
  65. _TEMPLATE_STAT locale::id ctype<wchar_t>::id;
  66. _TEMPLATE_STAT locale::id codecvt<wchar_t, char, mbstate_t>::id;
  67. #ifdef _NATIVE_WCHAR_T_DEFINED
  68. _TEMPLATE_STAT locale::id ctype<unsigned short>::id;
  69. _TEMPLATE_STAT locale::id codecvt<unsigned short, char, mbstate_t>::id;
  70. #endif
  71. _TEMPLATE_STAT const size_t ctype<char>::table_size =
  72. 1 << CHAR_BIT; // size of ctype mapping table, typically 256
  73. locale::locale() _THROW0()
  74. : _Ptr(_Init())
  75. { // construct from current locale
  76. ::_Getgloballocale()->_Incref();
  77. }
  78. const locale& __cdecl locale::classic()
  79. { // get reference to "C" locale
  80. _Init();
  81. return (classic_locale);
  82. }
  83. locale __cdecl locale::empty()
  84. { // make empty transparent locale
  85. _Init();
  86. return (locale(_NEW_CRT _Locimp(true)));
  87. }
  88. const locale::facet *locale::_Getfacet(size_t id) const
  89. { // look up a facet in locale object
  90. const facet *facptr = id < _Ptr->_Facetcount
  91. ? _Ptr->_Facetvec[id] : 0; // null if id off end
  92. if (facptr != 0 || !_Ptr->_Xparent)
  93. return (facptr); // found facet or not transparent, return pointer
  94. else
  95. { // look in current locale
  96. locale::_Locimp *_Ptr = ::_Getgloballocale();
  97. return (id < _Ptr->_Facetcount
  98. ? _Ptr->_Facetvec[id] // get from current locale
  99. : 0); // no entry in current locale
  100. }
  101. }
  102. bool locale::operator==(const locale& loc) const
  103. { // compare locales for equality
  104. return (_Ptr == loc._Ptr
  105. || name().compare("*") != 0 && name().compare(loc.name()) == 0);
  106. }
  107. locale::_Locimp *__cdecl locale::_Init()
  108. { // setup global and "C" locales
  109. locale::_Locimp *_Ptr = ::_Getgloballocale();
  110. if (_Ptr == 0)
  111. { // lock and test again
  112. _Lockit lock(_LOCK_LOCALE); // prevent double initialization
  113. _Ptr = ::_Getgloballocale();
  114. if (_Ptr == 0)
  115. { // create new locales
  116. ::_Setgloballocale(_Ptr = _NEW_CRT _Locimp);
  117. _Ptr->_Catmask = all; // set current locale to "C"
  118. _Ptr->_Name = "C";
  119. _Locimp::_Clocptr = _Ptr; // set classic to match
  120. _Locimp::_Clocptr->_Incref();
  121. new (&classic_locale) locale(_Locimp::_Clocptr);
  122. }
  123. }
  124. return (_Ptr);
  125. }
  126. void locale::facet::_Register()
  127. { // queue up lazy facet for destruction
  128. if (_Fac_head == 0)
  129. ::_Atexit(&_Fac_tidy);
  130. _Fac_head = _NEW_CRT _Fac_node(_Fac_head, this);
  131. }
  132. locale::_Locimp::_Locimp(bool transparent)
  133. : locale::facet(1), _Facetvec(0), _Facetcount(0),
  134. _Catmask(none), _Xparent(transparent), _Name("*")
  135. { // construct an empty _Locimp
  136. }
  137. locale::_Locimp::~_Locimp()
  138. { // destruct a _Locimp
  139. _Lockit lock(_LOCK_LOCALE); // prevent double delete
  140. for (size_t count = _Facetcount; 0 < count; )
  141. if (_Facetvec[--count] != 0)
  142. _DELETE_CRT(_Facetvec[count]->_Decref());
  143. free(_Facetvec);
  144. }
  145. _Locinfo::_Locinfo(const char *locname)
  146. : _Lock(_LOCK_LOCALE)
  147. { // switch to a named locale
  148. _Oldlocname = setlocale(LC_ALL, 0);
  149. _Newlocname = locname == 0
  150. || (locname = setlocale(LC_ALL, locname)) == 0
  151. ? "*" : locname;
  152. }
  153. _Locinfo::~_Locinfo()
  154. { // destroy a _Locinfo object, revert locale
  155. if (0 < _Oldlocname.size())
  156. setlocale(LC_ALL, _Oldlocname.c_str());
  157. }
  158. _STD_END
  159. /*
  160. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  161. * Consult your license regarding permissions and restrictions.
  162. V3.10:0009 */