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.

196 lines
7.1 KiB

  1. // locale -- class locale member functions
  2. #include <cstdlib>
  3. #include <istream>
  4. #include <locale>
  5. _STD_BEGIN
  6. typedef char_traits<char> _Traits;
  7. typedef istreambuf_iterator<char, _Traits> _Initer;
  8. typedef ostreambuf_iterator<char, _Traits> _Outiter;
  9. locale::locale(const locale& _X, const locale& _Y, category _C)
  10. : _Ptr(new _Locimp(*_X._Ptr))
  11. { // construct a locale by copying named facets
  12. _Locinfo _Lobj(_X._Ptr->_Cat, _X._Ptr->_Name.c_str());
  13. _Locimp::_Makeloc(_Lobj._Addcats(_C & _Y._Ptr->_Cat,
  14. _Y._Ptr->_Name.c_str()), _C, _Ptr, &_Y);
  15. }
  16. locale::locale(const char *_S, category _C)
  17. : _Ptr(new _Locimp)
  18. { // construct a locale with named facets
  19. _Init();
  20. _Locinfo _Lobj(_C, _S);
  21. if (_Lobj._Getname().compare("*") == 0)
  22. _THROW(runtime_error, "bad locale name");
  23. _Locimp::_Makeloc(_Lobj, _C, _Ptr, 0);
  24. }
  25. locale::locale(const locale& _X, const char *_S, category _C)
  26. : _Ptr(new _Locimp(*_X._Ptr))
  27. { // construct a locale by copying, replacing named facets
  28. _Locinfo _Lobj(_C, _S);
  29. if (_Lobj._Getname().compare("*") == 0)
  30. _THROW(runtime_error, "bad locale name");
  31. _Locimp::_Makeloc(_Lobj._Addcats(_Ptr->_Cat,
  32. _Ptr->_Name.c_str()), _C, _Ptr, 0);
  33. }
  34. locale& locale::_Addfac(facet *_Fac, size_t _Id, size_t _Cat)
  35. { // add a facet, copying on write
  36. if (1 < _Ptr->_Refs)
  37. {_Ptr->_Decref();
  38. _Ptr = new _Locimp(*_Ptr); }
  39. _Ptr->_Addfac(_Fac, _Id);
  40. if (_Cat != 0)
  41. _Ptr->_Name = "*";
  42. return (*this); }
  43. locale __cdecl locale::global(const locale& _X)
  44. { // change global locale
  45. locale _L;
  46. _Lockit _Lk;
  47. if (_Locimp::_Global != _X._Ptr)
  48. { // set new global locale
  49. delete _Locimp::_Global->_Decref();
  50. _Locimp::_Global = _X._Ptr;
  51. _Locimp::_Global->_Incref();
  52. category _Cmask = _Locimp::_Global->_Cat & all;
  53. if (_Cmask == all)
  54. setlocale(LC_ALL, _Locimp::_Global->_Name.c_str());
  55. else
  56. for (int _Cat = 0; _Cat <= _LC_MAX; ++_Cat)
  57. if ((_CATMASK(_Cat) & _Cmask) != 0)
  58. setlocale(_Cat,
  59. _Locimp::_Global->_Name.c_str());
  60. }
  61. return (_L);
  62. }
  63. // facets associated with C categories
  64. #define ADDFAC(T, cat, pi, pl) \
  65. if ((_CATMASK(T::_Getcat()) & cat) == 0) \
  66. ; \
  67. else if (pl == 0) \
  68. pi->_Addfac(new T(_Lobj), T::id); \
  69. else \
  70. pi->_Addfac((locale::facet *)&_USE(*pl, T), T::id);
  71. typedef ctype<char> _T1;
  72. typedef num_get<char, _Initer> _T2;
  73. typedef num_put<char, _Outiter> _T3;
  74. typedef numpunct<char> _T4;
  75. typedef codecvt<char, char, mbstate_t> _Tc1;
  76. template<> locale::id ctype<char>::id;
  77. template<> locale::id codecvt<char,char,int>::id;
  78. template<> locale::id num_get<char, _Initer>::id;
  79. template<> locale::id num_put<char, _Outiter>::id;
  80. template<> locale::id numpunct<char>::id;
  81. locale::_Locimp *__cdecl locale::_Locimp::_Makeloc(
  82. const _Locinfo& _Lobj, locale::category _C,
  83. _Locimp *_Pi, const locale *_Pl)
  84. { // setup a new locale
  85. _Lockit _Lk;
  86. ADDFAC(_T1, _C, _Pi, _Pl);
  87. ADDFAC(_T2, _C, _Pi, _Pl);
  88. ADDFAC(_T3, _C, _Pi, _Pl);
  89. ADDFAC(_T4, _C, _Pi, _Pl);
  90. //...
  91. ADDFAC(_Tc1, _C, _Pi, _Pl);
  92. _Locimp::_Makexloc(_Lobj, _C, _Pi, _Pl);
  93. _Locimp::_Makewloc(_Lobj, _C, _Pi, _Pl);
  94. _Pi->_Cat |= _C;
  95. _Pi->_Name = _Lobj._Getname();
  96. return (_Pi);
  97. }
  98. locale::_Locimp::_Locimp(const locale::_Locimp& _X)
  99. : locale::facet(1), _Fv(0), _Nfv(_X._Nfv),
  100. _Cat(_X._Cat), _Xpar(_X._Xpar), _Name(_X._Name)
  101. { // construct a _Locimp from a copy
  102. _Lockit Lk;
  103. if (&_X == _Clocptr)
  104. _Makeloc(_Locinfo(), locale::all, this, 0);
  105. else
  106. {_Lockit _Lk;
  107. if (0 < _Nfv)
  108. { // copy over nonempty facet vector
  109. if ((_Fv = (locale::facet **)malloc(
  110. _Nfv * sizeof (locale::facet *))) == 0)
  111. _Nomemory();
  112. for (size_t _N = _Nfv; 0 < _N; )
  113. { // copy over facet pointers
  114. locale::facet *_Pf = _X._Fv[--_N];
  115. if ((_Fv[_N] = _Pf) != 0)
  116. _Pf->_Incref();
  117. }
  118. }
  119. }
  120. }
  121. void locale::_Locimp::_Addfac(locale::facet *_Pf, size_t _Id)
  122. { // add a facet to a locale
  123. _Lockit _Lk;
  124. const size_t _MINCAT = 32;
  125. if (_Nfv <= _Id)
  126. { // make facet vector larger
  127. size_t _N = _Id + 1;
  128. if (_N < _MINCAT)
  129. _N = _MINCAT;
  130. locale::facet **_Pvn = (locale::facet **)realloc(_Fv,
  131. _N * sizeof (locale::facet **));
  132. if (_Pvn == 0)
  133. _Nomemory();
  134. _Fv = _Pvn;
  135. for (; _Nfv < _N; ++_Nfv)
  136. _Fv[_Nfv] = 0;
  137. }
  138. _Pf->_Incref();
  139. if (_Fv[_Id] != 0)
  140. delete _Fv[_Id]->_Decref();
  141. _Fv[_Id] = _Pf;
  142. }
  143. _CRTIMP2 _Locinfo::_Locinfo(const char *_Name)
  144. { // switch to a named locale
  145. _Lockit _Lk;
  146. _Oname = setlocale(LC_ALL, 0);
  147. _Nname = _Name == 0
  148. || (_Name = setlocale(LC_ALL, _Name)) == 0
  149. ? "*" : _Name; }
  150. _CRTIMP2 _Locinfo::_Locinfo(int _C, const char *_Name)
  151. {
  152. _Lockit _Lk;
  153. _Addcats(_C, _Name);
  154. }
  155. _CRTIMP2 _Locinfo::~_Locinfo()
  156. { // destroy a _Locinfo object, revert locale
  157. if (0 < _Oname.size())
  158. setlocale(LC_ALL, _Oname.c_str()); }
  159. _CRTIMP2 _Locinfo& _Locinfo::_Addcats(int _C, const char *_Name)
  160. { // merge in another named locale
  161. const char *_Lname = 0;
  162. if (_C == 0)
  163. _Lname = setlocale(LC_ALL, 0);
  164. else if (_C == _M_ALL)
  165. _Lname = setlocale(LC_ALL, _Name);
  166. else
  167. for (int _Cat = 0; _Cat <= _LC_MAX; ++_Cat)
  168. if ((_CATMASK(_Cat) & _C) != 0)
  169. _Lname = setlocale(_Cat, _Name);
  170. _Nname = _Lname != 0 ? _Lname : "*";
  171. return (*this); }
  172. _STD_END
  173. /*
  174. * Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
  175. * Consult your license regarding permissions and restrictions.
  176. */