epoc32/include/stdapis/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  * © 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 */