epoc32/include/stdapis/stlport/stl/_ostream.c
branchSymbian2
changeset 2 2fe1408b6811
parent 0 061f57f2323e
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
     1 _ostream.c
     1 /*
       
     2  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
       
     3  *
       
     4  * Copyright (c) 1999
       
     5  * Silicon Graphics Computer Systems, Inc.
       
     6  *
       
     7  * Copyright (c) 1999 
       
     8  * Boris Fomitchev
       
     9  *
       
    10  * This material is provided "as is", with absolutely no warranty expressed
       
    11  * or implied. Any use is at your own risk.
       
    12  *
       
    13  * Permission to use or copy this software for any purpose is hereby granted 
       
    14  * without fee, provided the above notices are retained on all copies.
       
    15  * Permission to modify the code and to distribute modified code is granted,
       
    16  * provided the above notices are retained, and a notice that the code was
       
    17  * modified is included with the above copyright notice.
       
    18  *
       
    19  */ 
       
    20 #ifndef _STLP_OSTREAM_C
       
    21 #define _STLP_OSTREAM_C
       
    22 
       
    23 
       
    24 #ifndef _STLP_INTERNAL_OSTREAM_H
       
    25 # include <stl/_ostream.h>
       
    26 #endif
       
    27 
       
    28 #if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION)
       
    29 
       
    30 #if !defined (_STLP_INTERNAL_NUM_PUT_H)
       
    31 # include <stl/_num_put.h>            // For basic_streambuf and iterators
       
    32 #endif
       
    33 
       
    34 _STLP_BEGIN_NAMESPACE
       
    35 
       
    36 // Helper functions for istream<>::sentry constructor.
       
    37 template <class _CharT, class _Traits>
       
    38 bool
       
    39 _M_init(basic_ostream<_CharT, _Traits>& __str) {
       
    40   if (__str.good()) {
       
    41     // boris : check if this is needed !
       
    42     if (!__str.rdbuf())
       
    43       __str.setstate(ios_base::badbit);
       
    44     if (__str.tie())
       
    45       __str.tie()->flush();
       
    46     return __str.good();
       
    47   } else
       
    48     return false;
       
    49 }
       
    50 
       
    51 //----------------------------------------------------------------------
       
    52 // Definitions of non-inline member functions.
       
    53 
       
    54 // Constructor, destructor
       
    55 
       
    56 template <class _CharT, class _Traits>
       
    57 _STLP_EXP_DECLSPEC basic_ostream<_CharT, _Traits>
       
    58   ::basic_ostream(basic_streambuf<_CharT, _Traits>* __buf)
       
    59     : basic_ios<_CharT, _Traits>() 
       
    60 {
       
    61   this->init(__buf);
       
    62 }
       
    63 
       
    64 template <class _CharT, class _Traits>
       
    65 _STLP_EXP_DECLSPEC basic_ostream<_CharT, _Traits>::~basic_ostream()
       
    66 {}
       
    67 
       
    68 // Output directly from a streambuf.
       
    69 template <class _CharT, class _Traits>
       
    70 _STLP_EXP_DECLSPEC basic_ostream<_CharT, _Traits>& 
       
    71 basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<_CharT, _Traits>* __from)
       
    72 {
       
    73   sentry __sentry(*this);
       
    74   if (__sentry) {
       
    75     if (__from) {
       
    76       bool __any_inserted = __from->gptr() != __from->egptr()
       
    77         ? this->_M_copy_buffered(__from, this->rdbuf())
       
    78         : this->_M_copy_unbuffered(__from, this->rdbuf());
       
    79       if (!__any_inserted)
       
    80         this->setstate(ios_base::failbit);
       
    81     }
       
    82     else
       
    83       this->setstate(ios_base::badbit);
       
    84   }
       
    85 
       
    86   return *this;
       
    87 }
       
    88 
       
    89 // Helper functions for the streambuf version of operator<<.  The
       
    90 // exception-handling code is complicated because exceptions thrown
       
    91 // while extracting characters are treated differently than exceptions
       
    92 // thrown while inserting characters.
       
    93 
       
    94 template <class _CharT, class _Traits>
       
    95 bool basic_ostream<_CharT, _Traits>
       
    96   ::_M_copy_buffered(basic_streambuf<_CharT, _Traits>* __from,
       
    97                      basic_streambuf<_CharT, _Traits>* __to)
       
    98 {
       
    99   bool __any_inserted = false;
       
   100 
       
   101   while (__from->egptr() != __from->gptr()) {
       
   102     const ptrdiff_t __avail = __from->egptr() - __from->gptr();
       
   103 
       
   104     streamsize __nwritten;
       
   105     _STLP_TRY {
       
   106       __nwritten = __to->sputn(__from->gptr(), __avail);
       
   107       __from->gbump((int)__nwritten);
       
   108     }
       
   109     _STLP_CATCH_ALL {
       
   110       this->_M_handle_exception(ios_base::badbit);
       
   111       return __any_inserted;
       
   112     }
       
   113 
       
   114     if (__nwritten == __avail) {
       
   115       _STLP_TRY {
       
   116         if (this->_S_eof(__from->sgetc()))
       
   117           return true;
       
   118         else
       
   119           __any_inserted = true;
       
   120       }
       
   121       _STLP_CATCH_ALL {
       
   122         this->_M_handle_exception(ios_base::failbit);
       
   123         return false;
       
   124       }
       
   125     }
       
   126 
       
   127     else if (__nwritten != 0)
       
   128       return true;
       
   129 
       
   130     else
       
   131       return __any_inserted;
       
   132   }
       
   133 
       
   134   // No characters are in the buffer, but we aren't at EOF.  Switch to
       
   135   // unbuffered mode.
       
   136   return __any_inserted || this->_M_copy_unbuffered(__from, __to);
       
   137 }
       
   138 
       
   139 template <class _CharT, class _Traits>
       
   140 bool basic_ostream<_CharT, _Traits>
       
   141   ::_M_copy_unbuffered(basic_streambuf<_CharT, _Traits>* __from,
       
   142                        basic_streambuf<_CharT, _Traits>* __to)
       
   143 {
       
   144   bool __any_inserted = false;
       
   145 
       
   146 #ifdef __SYMBIAN32__
       
   147   int_type __c;
       
   148     _STLP_TRY {
       
   149   __c = __from->sgetc();;
       
   150     }
       
   151     _STLP_CATCH_ALL {
       
   152       this->_M_handle_exception(ios_base::failbit);
       
   153       return __any_inserted;
       
   154     }
       
   155   for(;;){
       
   156 
       
   157     if (this->_S_eof(__c))
       
   158       return __any_inserted;
       
   159 
       
   160     else {
       
   161       int_type __tmp;
       
   162       _STLP_TRY {
       
   163         __tmp = __to->sputc(__c);
       
   164       }
       
   165       _STLP_CATCH_ALL {
       
   166         this->_M_handle_exception(ios_base::badbit);
       
   167         return __any_inserted;
       
   168       }
       
   169 
       
   170       if (this->_S_eof(__tmp)) {
       
   171         break;
       
   172       }
       
   173       else
       
   174         __any_inserted = true;
       
   175     }
       
   176     _STLP_TRY {
       
   177       __c = __from->snextc();
       
   178     }
       
   179     _STLP_CATCH_ALL {
       
   180       this->_M_handle_exception(ios_base::failbit);
       
   181       return __any_inserted;
       
   182     }
       
   183   }
       
   184 #else
       
   185   while (true) {
       
   186     int_type __c;
       
   187     _STLP_TRY {
       
   188       __c = __from->sbumpc();
       
   189     }
       
   190     _STLP_CATCH_ALL {
       
   191       this->_M_handle_exception(ios_base::failbit);
       
   192       return __any_inserted;
       
   193     }
       
   194 
       
   195     if (this->_S_eof(__c))
       
   196       return __any_inserted;
       
   197 
       
   198     else {
       
   199       int_type __tmp;
       
   200       _STLP_TRY {
       
   201         __tmp = __to->sputc(__c);
       
   202       }
       
   203       _STLP_CATCH_ALL {
       
   204         this->_M_handle_exception(ios_base::badbit);
       
   205         return __any_inserted;
       
   206       }
       
   207 
       
   208       if (this->_S_eof(__tmp)) {
       
   209         _STLP_TRY {
       
   210           /* __tmp = */ __from->sputbackc(__c);
       
   211         }
       
   212         _STLP_CATCH_ALL {
       
   213           this->_M_handle_exception(ios_base::badbit);
       
   214           return __any_inserted;
       
   215         }
       
   216       }
       
   217       else
       
   218         __any_inserted = true;
       
   219     }
       
   220   }
       
   221 #endif
       
   222   return __any_inserted;
       
   223 }
       
   224 
       
   225 // Helper function for numeric output.
       
   226 
       
   227 template <class _CharT, class _Traits, class _Number>
       
   228 basic_ostream<_CharT, _Traits>&  _STLP_CALL
       
   229 _M_put_num(basic_ostream<_CharT, _Traits>& __os, _Number __x)
       
   230 {
       
   231   typedef typename basic_ostream<_CharT, _Traits>::sentry _Sentry;
       
   232   _Sentry __sentry(__os);
       
   233   bool __failed = true;
       
   234 
       
   235   if (__sentry) {
       
   236     _STLP_TRY {
       
   237       typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > _NumPut;      
       
   238       __failed = (use_facet<_NumPut>(__os.getloc())).put(
       
   239                                                          ostreambuf_iterator<_CharT, _Traits>(__os.rdbuf()), 
       
   240                                                          __os, __os.fill(),
       
   241                                                          __x).failed();
       
   242     }
       
   243     _STLP_CATCH_ALL {
       
   244       __os._M_handle_exception(ios_base::badbit);
       
   245     }
       
   246   }
       
   247   if (__failed)
       
   248     __os.setstate(ios_base::badbit); 
       
   249   return __os;
       
   250 }
       
   251 
       
   252 # if defined (_STLP_USE_TEMPLATE_EXPORT)  && defined (__BUILDING_STLPORT)
       
   253 _STLP_EXPORT_TEMPLATE _STLP_EXP_DECLSPEC basic_ostream<char, char_traits<char> >& _STLP_CALL
       
   254 _M_put_num(basic_ostream<char, char_traits<char> >&, unsigned long);
       
   255 _STLP_EXPORT_TEMPLATE _STLP_EXP_DECLSPEC basic_ostream<char, char_traits<char> >&  _STLP_CALL
       
   256 _M_put_num(basic_ostream<char, char_traits<char> >&, long);
       
   257 #  if defined (_STLP_LONG_LONG)
       
   258 _STLP_EXPORT_TEMPLATE _STLP_EXP_DECLSPEC basic_ostream<char, char_traits<char> >&  _STLP_CALL
       
   259 _M_put_num(basic_ostream<char, char_traits<char> >&, unsigned _STLP_LONG_LONG);
       
   260 _STLP_EXPORT_TEMPLATE _STLP_EXP_DECLSPEC basic_ostream<char, char_traits<char> >&  _STLP_CALL
       
   261 _M_put_num(basic_ostream<char, char_traits<char> >&, _STLP_LONG_LONG );
       
   262 #  endif
       
   263 # endif
       
   264 
       
   265 template <class _CharT, class _Traits>
       
   266 void basic_ostream<_CharT, _Traits>::_M_put_char(_CharT __c)
       
   267 {
       
   268   sentry __sentry(*this);
       
   269   if (__sentry) {
       
   270     bool __failed = true;
       
   271     _STLP_TRY {
       
   272       streamsize __npad = this->width() > 0 ? this->width() - 1 : 0;
       
   273       //      if (__npad <= 1)
       
   274       if (__npad == 0)
       
   275         __failed = this->_S_eof(this->rdbuf()->sputc(__c));
       
   276       else if ((this->flags() & ios_base::adjustfield) == ios_base::left) {
       
   277         __failed = this->_S_eof(this->rdbuf()->sputc(__c));
       
   278         __failed = __failed || 
       
   279                    this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
       
   280       }
       
   281       else {
       
   282         __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
       
   283         __failed = __failed || this->_S_eof(this->rdbuf()->sputc(__c));
       
   284       }
       
   285 
       
   286       this->width(0);
       
   287     }
       
   288     _STLP_CATCH_ALL {
       
   289       this->_M_handle_exception(ios_base::badbit);
       
   290     }
       
   291 
       
   292     if (__failed)
       
   293       this->setstate(ios_base::badbit);
       
   294   }
       
   295 }
       
   296 
       
   297 template <class _CharT, class _Traits>
       
   298 void basic_ostream<_CharT, _Traits>::_M_put_nowiden(const _CharT* __s)
       
   299 {
       
   300   sentry __sentry(*this);
       
   301   if (__sentry) {
       
   302     bool __failed = true;
       
   303     streamsize __n = _Traits::length(__s);
       
   304     streamsize __npad = this->width() > __n ? this->width() - __n : 0;
       
   305 
       
   306     _STLP_TRY {
       
   307       if (__npad == 0)
       
   308         __failed = this->rdbuf()->sputn(__s, __n) != __n;
       
   309       else if ((this->flags() & ios_base::adjustfield) == ios_base::left) {
       
   310         __failed = this->rdbuf()->sputn(__s, __n) != __n;
       
   311         __failed = __failed || 
       
   312                    this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
       
   313       }
       
   314       else {
       
   315         __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
       
   316         __failed = __failed || this->rdbuf()->sputn(__s, __n) != __n;
       
   317       }
       
   318 
       
   319       this->width(0);
       
   320     }
       
   321     _STLP_CATCH_ALL {
       
   322       this->_M_handle_exception(ios_base::badbit);
       
   323     }
       
   324 
       
   325     if (__failed)
       
   326       this->setstate(ios_base::failbit);
       
   327   }
       
   328 }
       
   329 
       
   330 template <class _CharT, class _Traits>
       
   331 void basic_ostream<_CharT, _Traits>::_M_put_widen(const char* __s)
       
   332 {
       
   333   sentry __sentry(*this);
       
   334   if (__sentry) {
       
   335     bool __failed = true;
       
   336     streamsize __n = char_traits<char>::length(__s);
       
   337     streamsize __npad = this->width() > __n ? this->width() - __n : 0;
       
   338 
       
   339     _STLP_TRY {
       
   340       if (__npad == 0)
       
   341         __failed = !this->_M_put_widen_aux(__s, __n);
       
   342       else if ((this->flags() & ios_base::adjustfield) == ios_base::left) {
       
   343         __failed = !this->_M_put_widen_aux(__s, __n);
       
   344         __failed = __failed || 
       
   345                    this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
       
   346       }
       
   347       else {
       
   348         __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad;
       
   349         __failed = __failed || !this->_M_put_widen_aux(__s, __n);
       
   350       }
       
   351 
       
   352       this->width(0);
       
   353     }
       
   354     _STLP_CATCH_ALL {
       
   355       this->_M_handle_exception(ios_base::badbit);
       
   356     }
       
   357 
       
   358     if (__failed)
       
   359       this->setstate(ios_base::failbit);
       
   360   }
       
   361 }
       
   362 
       
   363 template <class _CharT, class _Traits>
       
   364 bool basic_ostream<_CharT, _Traits>::_M_put_widen_aux(const char* __s,
       
   365                                                       streamsize __n)
       
   366 {
       
   367   basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
       
   368 
       
   369   for ( ; __n > 0 ; --__n)
       
   370     if (this->_S_eof(__buf->sputc(this->widen(*__s++))))
       
   371       return false;
       
   372   return true;
       
   373 }
       
   374 
       
   375 // Unformatted output of a single character.
       
   376 template <class _CharT, class _Traits>
       
   377 _STLP_EXP_DECLSPEC basic_ostream<_CharT, _Traits>&
       
   378 basic_ostream<_CharT, _Traits>::put(char_type __c)
       
   379 {
       
   380   sentry __sentry(*this);
       
   381   bool __failed = true;
       
   382 
       
   383   if (__sentry) {
       
   384     _STLP_TRY {
       
   385       __failed = this->_S_eof(this->rdbuf()->sputc(__c));
       
   386     }
       
   387     _STLP_CATCH_ALL {
       
   388       this->_M_handle_exception(ios_base::badbit);
       
   389     }
       
   390   }
       
   391 
       
   392   if (__failed)
       
   393     this->setstate(ios_base::badbit);
       
   394 
       
   395   return *this;
       
   396 }
       
   397 
       
   398 // Unformatted output of a single character.
       
   399 template <class _CharT, class _Traits>
       
   400 _STLP_EXP_DECLSPEC basic_ostream<_CharT, _Traits>&
       
   401 basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)
       
   402 {
       
   403   sentry __sentry(*this);
       
   404   bool __failed = true;
       
   405 
       
   406   if (__sentry) {
       
   407     _STLP_TRY {
       
   408       __failed = this->rdbuf()->sputn(__s, __n) != __n;
       
   409     }
       
   410     _STLP_CATCH_ALL {
       
   411       this->_M_handle_exception(ios_base::badbit);
       
   412     }
       
   413   }
       
   414 
       
   415   if (__failed)
       
   416     this->setstate(ios_base::badbit);
       
   417 
       
   418   return *this;
       
   419 }
       
   420 
       
   421 _STLP_END_NAMESPACE
       
   422 
       
   423 #endif /* defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) */
       
   424 
       
   425 #endif /* _STLP_OSTREAM_C */