/project/jni/stlport/stlport/stl/_ostream.c

https://github.com/aichunyu/FFPlayer · C · 446 lines · 337 code · 64 blank · 45 comment · 66 complexity · 717c92a85c0761b7218b8696bb27dd17 MD5 · raw file

  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. #ifndef _STLP_OSTREAM_C
  19. #define _STLP_OSTREAM_C
  20. #ifndef _STLP_INTERNAL_OSTREAM_H
  21. # include <stl/_ostream.h>
  22. #endif
  23. #if !defined (_STLP_INTERNAL_NUM_PUT_H)
  24. # include <stl/_num_put.h> // For basic_streambuf and iterators
  25. #endif
  26. _STLP_BEGIN_NAMESPACE
  27. //----------------------------------------------------------------------
  28. // Definitions of non-inline member functions.
  29. // Constructor, destructor
  30. template <class _CharT, class _Traits>
  31. basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<_CharT, _Traits>* __buf)
  32. : basic_ios<_CharT, _Traits>() {
  33. this->init(__buf);
  34. }
  35. template <class _CharT, class _Traits>
  36. basic_ostream<_CharT, _Traits>::~basic_ostream()
  37. {}
  38. // Output directly from a streambuf.
  39. template <class _CharT, class _Traits>
  40. basic_ostream<_CharT, _Traits>&
  41. basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<_CharT, _Traits>* __from) {
  42. sentry __sentry(*this);
  43. if (__sentry) {
  44. if (__from) {
  45. bool __any_inserted = __from->gptr() != __from->egptr()
  46. ? this->_M_copy_buffered(__from, this->rdbuf())
  47. : this->_M_copy_unbuffered(__from, this->rdbuf());
  48. if (!__any_inserted)
  49. this->setstate(ios_base::failbit);
  50. }
  51. else
  52. this->setstate(ios_base::badbit);
  53. }
  54. return *this;
  55. }
  56. // Helper functions for the streambuf version of operator<<. The
  57. // exception-handling code is complicated because exceptions thrown
  58. // while extracting characters are treated differently than exceptions
  59. // thrown while inserting characters.
  60. template <class _CharT, class _Traits>
  61. bool basic_ostream<_CharT, _Traits>
  62. ::_M_copy_buffered(basic_streambuf<_CharT, _Traits>* __from,
  63. basic_streambuf<_CharT, _Traits>* __to) {
  64. bool __any_inserted = false;
  65. while (__from->egptr() != __from->gptr()) {
  66. const ptrdiff_t __avail = __from->egptr() - __from->gptr();
  67. streamsize __nwritten;
  68. _STLP_TRY {
  69. __nwritten = __to->sputn(__from->gptr(), __avail);
  70. __from->gbump((int)__nwritten);
  71. }
  72. _STLP_CATCH_ALL {
  73. this->_M_handle_exception(ios_base::badbit);
  74. return __any_inserted;
  75. }
  76. if (__nwritten == __avail) {
  77. _STLP_TRY {
  78. if (this->_S_eof(__from->sgetc()))
  79. return true;
  80. else
  81. __any_inserted = true;
  82. }
  83. _STLP_CATCH_ALL {
  84. this->_M_handle_exception(ios_base::failbit);
  85. return false;
  86. }
  87. }
  88. else if (__nwritten != 0)
  89. return true;
  90. else
  91. return __any_inserted;
  92. }
  93. // No characters are in the buffer, but we aren't at EOF. Switch to
  94. // unbuffered mode.
  95. return __any_inserted || this->_M_copy_unbuffered(__from, __to);
  96. }
  97. /*
  98. * Helper struct (guard) to put back a character in a streambuf
  99. * whenever an exception or an eof occur.
  100. */
  101. template <class _CharT, class _Traits>
  102. struct _SPutBackC {
  103. typedef basic_streambuf<_CharT, _Traits> _StreamBuf;
  104. typedef typename _StreamBuf::int_type int_type;
  105. _SPutBackC(_StreamBuf *pfrom)
  106. : __pfrom(pfrom), __c(0), __do_guard(false) {}
  107. ~_SPutBackC() {
  108. if (__do_guard) {
  109. __pfrom->sputbackc(_Traits::to_char_type(__c));
  110. }
  111. }
  112. void guard(int_type c) {
  113. __c = c;
  114. __do_guard = true;
  115. }
  116. void release() {
  117. __do_guard = false;
  118. }
  119. private:
  120. _StreamBuf *__pfrom;
  121. int_type __c;
  122. bool __do_guard;
  123. };
  124. template <class _CharT, class _Traits>
  125. bool basic_ostream<_CharT, _Traits>
  126. ::_M_copy_unbuffered(basic_streambuf<_CharT, _Traits>* __from,
  127. basic_streambuf<_CharT, _Traits>* __to) {
  128. typedef _SPutBackC<_CharT, _Traits> _SPutBackCGuard;
  129. bool __any_inserted = false;
  130. int_type __c;
  131. _STLP_TRY {
  132. _SPutBackCGuard __cguard(__from);
  133. for (;;) {
  134. _STLP_TRY {
  135. __c = __from->sbumpc();
  136. }
  137. _STLP_CATCH_ALL {
  138. this->_M_handle_exception(ios_base::failbit);
  139. return __any_inserted;
  140. }
  141. if ( this->_S_eof(__c) )
  142. return __any_inserted;
  143. __cguard.guard(__c);
  144. if ( this->_S_eof( __to->sputc(_Traits::to_char_type(__c)) ) ) {
  145. return __any_inserted;
  146. }
  147. __cguard.release();
  148. __any_inserted = true;
  149. }
  150. }
  151. _STLP_CATCH_ALL {
  152. this->_M_handle_exception(ios_base::badbit);
  153. return __any_inserted;
  154. }
  155. }
  156. _STLP_MOVE_TO_PRIV_NAMESPACE
  157. // Helper function for numeric output.
  158. template <class _CharT, class _Traits, class _Number>
  159. basic_ostream<_CharT, _Traits>& _STLP_CALL
  160. __put_num(basic_ostream<_CharT, _Traits>& __os, _Number __x) {
  161. typedef typename basic_ostream<_CharT, _Traits>::sentry _Sentry;
  162. _Sentry __sentry(__os);
  163. bool __failed = true;
  164. if (__sentry) {
  165. _STLP_TRY {
  166. typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > _NumPut;
  167. __failed = (use_facet<_NumPut>(__os.getloc())).put(ostreambuf_iterator<_CharT, _Traits>(__os.rdbuf()),
  168. __os, __os.fill(),
  169. __x).failed();
  170. }
  171. _STLP_CATCH_ALL {
  172. __os._M_handle_exception(ios_base::badbit);
  173. }
  174. }
  175. if (__failed)
  176. __os.setstate(ios_base::badbit);
  177. return __os;
  178. }
  179. _STLP_MOVE_TO_STD_NAMESPACE
  180. /*
  181. * In the following operators we try to limit code bloat by limiting the
  182. * number of __put_num instanciations.
  183. */
  184. template <class _CharT, class _Traits>
  185. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(short __x) {
  186. _STLP_STATIC_ASSERT( sizeof(short) <= sizeof(long) )
  187. long __tmp = ((this->flags() & _Basic_ios::basefield) != ios_base::dec) ?
  188. __STATIC_CAST(long, __STATIC_CAST(unsigned short, __x)): __x;
  189. return _STLP_PRIV __put_num(*this, __tmp);
  190. }
  191. template <class _CharT, class _Traits>
  192. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned short __x) {
  193. _STLP_STATIC_ASSERT( sizeof(unsigned short) <= sizeof(unsigned long) )
  194. return _STLP_PRIV __put_num(*this, __STATIC_CAST(unsigned long,__x));
  195. }
  196. template <class _CharT, class _Traits>
  197. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(int __x) {
  198. _STLP_STATIC_ASSERT( sizeof(int) <= sizeof(long) )
  199. long __tmp = ((this->flags() & _Basic_ios::basefield) != ios_base::dec) ?
  200. __STATIC_CAST(long, __STATIC_CAST(unsigned int, __x)): __x;
  201. return _STLP_PRIV __put_num(*this, __tmp);
  202. }
  203. template <class _CharT, class _Traits>
  204. #if defined (_WIN64) || !defined (_STLP_MSVC) || (_STLP_MSVC < 1300)
  205. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned int __x) {
  206. _STLP_STATIC_ASSERT( sizeof(unsigned int) <= sizeof(unsigned long) )
  207. #else
  208. /* We define this operator with size_t rather than unsigned int to avoid
  209. * 64 bits warning.
  210. */
  211. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(size_t __x) {
  212. _STLP_STATIC_ASSERT( sizeof(size_t) <= sizeof(unsigned long) )
  213. #endif
  214. return _STLP_PRIV __put_num(*this, __STATIC_CAST(unsigned long,__x));
  215. }
  216. template <class _CharT, class _Traits>
  217. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __x)
  218. { return _STLP_PRIV __put_num(*this, __x); }
  219. template <class _CharT, class _Traits>
  220. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __x)
  221. { return _STLP_PRIV __put_num(*this, __x); }
  222. #ifdef _STLP_LONG_LONG
  223. template <class _CharT, class _Traits>
  224. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (_STLP_LONG_LONG __x)
  225. { return _STLP_PRIV __put_num(*this, __x); }
  226. template <class _CharT, class _Traits>
  227. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (unsigned _STLP_LONG_LONG __x)
  228. { return _STLP_PRIV __put_num(*this, __x); }
  229. #endif
  230. template <class _CharT, class _Traits>
  231. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __x)
  232. { return _STLP_PRIV __put_num(*this, __STATIC_CAST(double,__x)); }
  233. template <class _CharT, class _Traits>
  234. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __x)
  235. { return _STLP_PRIV __put_num(*this, __x); }
  236. #ifndef _STLP_NO_LONG_DOUBLE
  237. template <class _CharT, class _Traits>
  238. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __x)
  239. { return _STLP_PRIV __put_num(*this, __x); }
  240. #endif
  241. template <class _CharT, class _Traits>
  242. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __x)
  243. { return _STLP_PRIV __put_num(*this, __x); }
  244. #ifndef _STLP_NO_BOOL
  245. template <class _CharT, class _Traits>
  246. basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __x)
  247. { return _STLP_PRIV __put_num(*this, __x); }
  248. #endif
  249. template <class _CharT, class _Traits>
  250. void basic_ostream<_CharT, _Traits>::_M_put_char(_CharT __c) {
  251. sentry __sentry(*this);
  252. if (__sentry) {
  253. bool __failed = true;
  254. _STLP_TRY {
  255. streamsize __npad = this->width() > 0 ? this->width() - 1 : 0;
  256. // if (__npad <= 1)
  257. if (__npad == 0)
  258. __failed = this->_S_eof(this->rdbuf()->sputc(__c));
  259. else if ((this->flags() & ios_base::adjustfield) == ios_base::left) {
  260. __failed = this->_S_eof(this->rdbuf()->sputc(__c));
  261. __failed = __failed ||
  262. this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
  263. }
  264. else {
  265. __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
  266. __failed = __failed || this->_S_eof(this->rdbuf()->sputc(__c));
  267. }
  268. this->width(0);
  269. }
  270. _STLP_CATCH_ALL {
  271. this->_M_handle_exception(ios_base::badbit);
  272. }
  273. if (__failed)
  274. this->setstate(ios_base::badbit);
  275. }
  276. }
  277. template <class _CharT, class _Traits>
  278. void basic_ostream<_CharT, _Traits>::_M_put_nowiden(const _CharT* __s) {
  279. sentry __sentry(*this);
  280. if (__sentry) {
  281. bool __failed = true;
  282. streamsize __n = _Traits::length(__s);
  283. streamsize __npad = this->width() > __n ? this->width() - __n : 0;
  284. _STLP_TRY {
  285. if (__npad == 0)
  286. __failed = this->rdbuf()->sputn(__s, __n) != __n;
  287. else if ((this->flags() & ios_base::adjustfield) == ios_base::left) {
  288. __failed = this->rdbuf()->sputn(__s, __n) != __n;
  289. __failed = __failed ||
  290. this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
  291. }
  292. else {
  293. __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
  294. __failed = __failed || this->rdbuf()->sputn(__s, __n) != __n;
  295. }
  296. this->width(0);
  297. }
  298. _STLP_CATCH_ALL {
  299. this->_M_handle_exception(ios_base::badbit);
  300. }
  301. if (__failed)
  302. this->setstate(ios_base::failbit);
  303. }
  304. }
  305. template <class _CharT, class _Traits>
  306. void basic_ostream<_CharT, _Traits>::_M_put_widen(const char* __s) {
  307. sentry __sentry(*this);
  308. if (__sentry) {
  309. bool __failed = true;
  310. streamsize __n = char_traits<char>::length(__s);
  311. streamsize __npad = this->width() > __n ? this->width() - __n : 0;
  312. _STLP_TRY {
  313. if (__npad == 0)
  314. __failed = !this->_M_put_widen_aux(__s, __n);
  315. else if ((this->flags() & ios_base::adjustfield) == ios_base::left) {
  316. __failed = !this->_M_put_widen_aux(__s, __n);
  317. __failed = __failed ||
  318. this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
  319. }
  320. else {
  321. __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
  322. __failed = __failed || !this->_M_put_widen_aux(__s, __n);
  323. }
  324. this->width(0);
  325. }
  326. _STLP_CATCH_ALL {
  327. this->_M_handle_exception(ios_base::badbit);
  328. }
  329. if (__failed)
  330. this->setstate(ios_base::failbit);
  331. }
  332. }
  333. template <class _CharT, class _Traits>
  334. bool basic_ostream<_CharT, _Traits>::_M_put_widen_aux(const char* __s,
  335. streamsize __n) {
  336. basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
  337. for ( ; __n > 0 ; --__n)
  338. if (this->_S_eof(__buf->sputc(this->widen(*__s++))))
  339. return false;
  340. return true;
  341. }
  342. // Unformatted output of a single character.
  343. template <class _CharT, class _Traits>
  344. basic_ostream<_CharT, _Traits>&
  345. basic_ostream<_CharT, _Traits>::put(char_type __c) {
  346. sentry __sentry(*this);
  347. bool __failed = true;
  348. if (__sentry) {
  349. _STLP_TRY {
  350. __failed = this->_S_eof(this->rdbuf()->sputc(__c));
  351. }
  352. _STLP_CATCH_ALL {
  353. this->_M_handle_exception(ios_base::badbit);
  354. }
  355. }
  356. if (__failed)
  357. this->setstate(ios_base::badbit);
  358. return *this;
  359. }
  360. // Unformatted output of a single character.
  361. template <class _CharT, class _Traits>
  362. basic_ostream<_CharT, _Traits>&
  363. basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n) {
  364. sentry __sentry(*this);
  365. bool __failed = true;
  366. if (__sentry) {
  367. _STLP_TRY {
  368. __failed = this->rdbuf()->sputn(__s, __n) != __n;
  369. }
  370. _STLP_CATCH_ALL {
  371. this->_M_handle_exception(ios_base::badbit);
  372. }
  373. }
  374. if (__failed)
  375. this->setstate(ios_base::badbit);
  376. return *this;
  377. }
  378. _STLP_END_NAMESPACE
  379. #endif /* _STLP_OSTREAM_C */
  380. // Local Variables:
  381. // mode:C++
  382. // End: