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