ios.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. */
  18. #include "stlport_prefix.h"
  19. #include <algorithm>
  20. #include <ios>
  21. #include <locale>
  22. #include <ostream> // for __get_ostreambuf definition
  23. #include "aligned_buffer.h"
  24. _STLP_BEGIN_NAMESPACE
  25. //----------------------------------------------------------------------
  26. // ios_base members
  27. // class ios_base::failure, a subclass of exception. It's used solely
  28. // for reporting errors.
  29. ios_base::failure::failure(const string& s)
  30. : __Named_exception(s)
  31. {}
  32. ios_base::failure::~failure() _STLP_NOTHROW_INHERENTLY {}
  33. #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
  34. // Definitions of ios_base's formatting flags.
  35. const ios_base::fmtflags ios_base::left;
  36. const ios_base::fmtflags ios_base::right;
  37. const ios_base::fmtflags ios_base::internal;
  38. const ios_base::fmtflags ios_base::dec;
  39. const ios_base::fmtflags ios_base::hex;
  40. const ios_base::fmtflags ios_base::oct;
  41. const ios_base::fmtflags ios_base::fixed;
  42. const ios_base::fmtflags ios_base::scientific;
  43. const ios_base::fmtflags ios_base::boolalpha;
  44. const ios_base::fmtflags ios_base::showbase;
  45. const ios_base::fmtflags ios_base::showpoint;
  46. const ios_base::fmtflags ios_base::showpos;
  47. const ios_base::fmtflags ios_base::skipws;
  48. const ios_base::fmtflags ios_base::unitbuf;
  49. const ios_base::fmtflags ios_base::uppercase;
  50. const ios_base::fmtflags ios_base::adjustfield;
  51. const ios_base::fmtflags ios_base::basefield;
  52. const ios_base::fmtflags ios_base::floatfield;
  53. // Definitions of ios_base's state flags.
  54. const ios_base::iostate ios_base::goodbit;
  55. const ios_base::iostate ios_base::badbit;
  56. const ios_base::iostate ios_base::eofbit;
  57. const ios_base::iostate ios_base::failbit;
  58. // Definitions of ios_base's openmode flags.
  59. const ios_base::openmode ios_base::app;
  60. const ios_base::openmode ios_base::ate;
  61. const ios_base::openmode ios_base::binary;
  62. const ios_base::openmode ios_base::in;
  63. const ios_base::openmode ios_base::out;
  64. const ios_base::openmode ios_base::trunc;
  65. // Definitions of ios_base's seekdir flags.
  66. const ios_base::seekdir ios_base::beg;
  67. const ios_base::seekdir ios_base::cur;
  68. const ios_base::seekdir ios_base::end;
  69. #endif
  70. // Internal functions used for managing exponentially-growing arrays of
  71. // POD types.
  72. // array is a pointer to N elements of type PODType. Expands the array,
  73. // if necessary, so that array[index] is meaningful. All new elements are
  74. // initialized to zero. Returns a pointer to the new array, and the new
  75. // size.
  76. template <class PODType>
  77. static pair<PODType*, size_t>
  78. _Stl_expand_array(PODType* __array, size_t N, int index) {
  79. if ((int)N < index + 1) {
  80. size_t new_N = (max)(2 * N, size_t(index + 1));
  81. PODType* new_array
  82. = __STATIC_CAST(PODType*,realloc(__array, new_N * sizeof(PODType)));
  83. if (new_array) {
  84. fill(new_array + N, new_array + new_N, PODType());
  85. return pair<PODType*, size_t>(new_array, new_N);
  86. }
  87. else
  88. return pair<PODType*, size_t>(__STATIC_CAST(PODType*,0), 0);
  89. }
  90. else
  91. return pair<PODType*, size_t>(__array, N);
  92. }
  93. // array is a pointer to N elements of type PODType. Allocate a new
  94. // array of N elements, copying the values from the old array to the new.
  95. // Return a pointer to the new array. It is assumed that array is non-null
  96. // and N is nonzero.
  97. template <class PODType>
  98. static PODType* _Stl_copy_array(const PODType* __array, size_t N) {
  99. PODType* result = __STATIC_CAST(PODType*,malloc(N * sizeof(PODType)));
  100. if (result)
  101. copy(__array, __array + N, result);
  102. return result;
  103. }
  104. locale ios_base::imbue(const locale& loc) {
  105. if (loc != _M_locale) {
  106. locale previous = _M_locale;
  107. _M_locale = loc;
  108. _M_invoke_callbacks(imbue_event);
  109. return previous;
  110. }
  111. else {
  112. _M_invoke_callbacks(imbue_event);
  113. return _M_locale;
  114. }
  115. }
  116. int _STLP_CALL ios_base::xalloc() {
  117. #if defined (_STLP_THREADS) && \
  118. defined (_STLP_WIN32THREADS) && defined (_STLP_NEW_PLATFORM_SDK)
  119. static volatile __stl_atomic_t _S_index = 0;
  120. return _STLP_ATOMIC_INCREMENT(&_S_index);
  121. #else
  122. static int _S_index = 0;
  123. static _STLP_STATIC_MUTEX __lock _STLP_MUTEX_INITIALIZER;
  124. _STLP_auto_lock sentry(__lock);
  125. return _S_index++;
  126. #endif
  127. }
  128. long& ios_base::iword(int index) {
  129. static long dummy = 0;
  130. pair<long*, size_t> tmp = _Stl_expand_array(_M_iwords, _M_num_iwords, index);
  131. if (tmp.first) { // The allocation, if any, succeeded.
  132. _M_iwords = tmp.first;
  133. _M_num_iwords = tmp.second;
  134. return _M_iwords[index];
  135. }
  136. else {
  137. _M_setstate_nothrow(badbit);
  138. _M_check_exception_mask();
  139. return dummy;
  140. }
  141. }
  142. void*& ios_base::pword(int index) {
  143. static void* dummy = 0;
  144. pair<void**, size_t> tmp = _Stl_expand_array(_M_pwords, _M_num_pwords, index);
  145. if (tmp.first) { // The allocation, if any, succeeded.
  146. _M_pwords = tmp.first;
  147. _M_num_pwords = tmp.second;
  148. return _M_pwords[index];
  149. }
  150. else {
  151. _M_setstate_nothrow(badbit);
  152. _M_check_exception_mask();
  153. return dummy;
  154. }
  155. }
  156. void ios_base::register_callback(event_callback __fn, int index) {
  157. pair<pair<event_callback, int>*, size_t> tmp
  158. = _Stl_expand_array(_M_callbacks, _M_num_callbacks, (int)_M_callback_index /* fbp: index ??? */ );
  159. if (tmp.first) {
  160. _M_callbacks = tmp.first;
  161. _M_num_callbacks = tmp.second;
  162. _M_callbacks[_M_callback_index++] = make_pair(__fn, index);
  163. }
  164. else {
  165. _M_setstate_nothrow(badbit);
  166. _M_check_exception_mask();
  167. }
  168. }
  169. // Invokes all currently registered callbacks for a particular event.
  170. // Behaves correctly even if one of the callbacks adds a new callback.
  171. void ios_base::_M_invoke_callbacks(event E) {
  172. for (size_t i = _M_callback_index; i > 0; --i) {
  173. event_callback f = _M_callbacks[i-1].first;
  174. int n = _M_callbacks[i-1].second;
  175. f(E, *this, n);
  176. }
  177. }
  178. // This function is called if the state, rdstate(), has a bit set
  179. // that is also set in the exception mask exceptions().
  180. void ios_base::_M_throw_failure() {
  181. const char* arg ;
  182. # if 0
  183. char buffer[256];
  184. char* ptr;
  185. strcpy(buffer, "ios failure: rdstate = 0x");
  186. ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_iostate));
  187. strcpy(ptr, " mask = 0x");
  188. ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_exception_mask));
  189. *ptr = 0;
  190. arg = buffer;
  191. # else
  192. arg = "ios failure";
  193. # endif
  194. # ifndef _STLP_USE_EXCEPTIONS
  195. fputs(arg, stderr);
  196. # else
  197. throw failure(arg);
  198. # endif
  199. }
  200. // Copy x's state to *this. This member function is used in the
  201. // implementation of basic_ios::copyfmt. Does not copy _M_exception_mask
  202. // or _M_iostate.
  203. void ios_base::_M_copy_state(const ios_base& x) {
  204. _M_fmtflags = x._M_fmtflags; // Copy the flags, except for _M_iostate
  205. _M_openmode = x._M_openmode; // and _M_exception_mask.
  206. _M_seekdir = x._M_seekdir;
  207. _M_precision = x._M_precision;
  208. _M_width = x._M_width;
  209. _M_locale = x._M_locale;
  210. if (x._M_callbacks) {
  211. pair<event_callback, int>* tmp = _Stl_copy_array(x._M_callbacks, x._M_callback_index);
  212. if (tmp) {
  213. free(_M_callbacks);
  214. _M_callbacks = tmp;
  215. _M_num_callbacks = _M_callback_index = x._M_callback_index;
  216. }
  217. else {
  218. _M_setstate_nothrow(badbit);
  219. _M_check_exception_mask();
  220. }
  221. }
  222. if (x._M_iwords) {
  223. long* tmp = _Stl_copy_array(x._M_iwords, x._M_num_iwords);
  224. if (tmp) {
  225. free(_M_iwords);
  226. _M_iwords = tmp;
  227. _M_num_iwords = x._M_num_iwords;
  228. }
  229. else {
  230. _M_setstate_nothrow(badbit);
  231. _M_check_exception_mask();
  232. }
  233. }
  234. if (x._M_pwords) {
  235. void** tmp = _Stl_copy_array(x._M_pwords, x._M_num_pwords);
  236. if (tmp) {
  237. free(_M_pwords);
  238. _M_pwords = tmp;
  239. _M_num_pwords = x._M_num_pwords;
  240. }
  241. else {
  242. _M_setstate_nothrow(badbit);
  243. _M_check_exception_mask();
  244. }
  245. }
  246. }
  247. // ios's (protected) default constructor. The standard says that all
  248. // fields have indeterminate values; we initialize them to zero for
  249. // simplicity. The only thing that really matters is that the arrays
  250. // are all initially null pointers, and the array element counts are all
  251. // initially zero.
  252. ios_base::ios_base()
  253. : _M_fmtflags(0), _M_iostate(0), _M_openmode(0), _M_seekdir(0),
  254. _M_exception_mask(0),
  255. _M_precision(0), _M_width(0),
  256. _M_locale(),
  257. _M_callbacks(0), _M_num_callbacks(0), _M_callback_index(0),
  258. _M_iwords(0), _M_num_iwords(0),
  259. _M_pwords(0),
  260. _M_num_pwords(0)
  261. {}
  262. // ios's destructor.
  263. ios_base::~ios_base() {
  264. _M_invoke_callbacks(erase_event);
  265. free(_M_callbacks);
  266. free(_M_iwords);
  267. free(_M_pwords);
  268. }
  269. //----------------------------------------------------------------------
  270. // Force instantiation of basic_ios
  271. // For DLL exports, they are already instantiated.
  272. #if !defined(_STLP_NO_FORCE_INSTANTIATE)
  273. template class _STLP_CLASS_DECLSPEC basic_ios<char, char_traits<char> >;
  274. # if !defined (_STLP_NO_WCHAR_T)
  275. template class _STLP_CLASS_DECLSPEC basic_ios<wchar_t, char_traits<wchar_t> >;
  276. # endif /* _STLP_NO_WCHAR_T */
  277. #endif
  278. _STLP_END_NAMESPACE
  279. // Local Variables:
  280. // mode:C++
  281. // End: