home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _ostream.c < prev    next >
C/C++ Source or Header  |  2002-02-02  |  11KB  |  383 lines

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