epoc32/include/tools/stlport/stl/_ostream.c
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     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: