Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_ostream.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 #ifndef _STLP_OSTREAM_C 00019 #define _STLP_OSTREAM_C 00020 00021 #ifndef _STLP_INTERNAL_OSTREAM_H 00022 # include <stl/_ostream.h> 00023 #endif 00024 00025 #if !defined (_STLP_INTERNAL_NUM_PUT_H) 00026 # include <stl/_num_put.h> // For basic_streambuf and iterators 00027 #endif 00028 00029 _STLP_BEGIN_NAMESPACE 00030 00031 //---------------------------------------------------------------------- 00032 // Definitions of non-inline member functions. 00033 00034 // Constructor, destructor 00035 00036 template <class _CharT, class _Traits> 00037 basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<_CharT, _Traits>* __buf) 00038 : basic_ios<_CharT, _Traits>() { 00039 this->init(__buf); 00040 } 00041 00042 template <class _CharT, class _Traits> 00043 basic_ostream<_CharT, _Traits>::~basic_ostream() 00044 {} 00045 00046 // Output directly from a streambuf. 00047 template <class _CharT, class _Traits> 00048 basic_ostream<_CharT, _Traits>& 00049 basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<_CharT, _Traits>* __from) { 00050 sentry __sentry(*this); 00051 if (__sentry) { 00052 if (__from) { 00053 bool __any_inserted = __from->gptr() != __from->egptr() 00054 ? this->_M_copy_buffered(__from, this->rdbuf()) 00055 : this->_M_copy_unbuffered(__from, this->rdbuf()); 00056 if (!__any_inserted) 00057 this->setstate(ios_base::failbit); 00058 } 00059 else 00060 this->setstate(ios_base::badbit); 00061 } 00062 00063 return *this; 00064 } 00065 00066 // Helper functions for the streambuf version of operator<<. The 00067 // exception-handling code is complicated because exceptions thrown 00068 // while extracting characters are treated differently than exceptions 00069 // thrown while inserting characters. 00070 00071 template <class _CharT, class _Traits> 00072 bool basic_ostream<_CharT, _Traits> 00073 ::_M_copy_buffered(basic_streambuf<_CharT, _Traits>* __from, 00074 basic_streambuf<_CharT, _Traits>* __to) { 00075 bool __any_inserted = false; 00076 00077 while (__from->egptr() != __from->gptr()) { 00078 const ptrdiff_t __avail = __from->egptr() - __from->gptr(); 00079 00080 streamsize __nwritten; 00081 _STLP_TRY { 00082 __nwritten = __to->sputn(__from->gptr(), __avail); 00083 __from->gbump((int)__nwritten); 00084 } 00085 _STLP_CATCH_ALL { 00086 this->_M_handle_exception(ios_base::badbit); 00087 return __any_inserted; 00088 } 00089 00090 if (__nwritten == __avail) { 00091 _STLP_TRY { 00092 if (this->_S_eof(__from->sgetc())) 00093 return true; 00094 else 00095 __any_inserted = true; 00096 } 00097 _STLP_CATCH_ALL { 00098 this->_M_handle_exception(ios_base::failbit); 00099 return false; 00100 } 00101 } 00102 else if (__nwritten != 0) 00103 return true; 00104 else 00105 return __any_inserted; 00106 } 00107 00108 // No characters are in the buffer, but we aren't at EOF. Switch to 00109 // unbuffered mode. 00110 return __any_inserted || this->_M_copy_unbuffered(__from, __to); 00111 } 00112 00113 /* 00114 * Helper struct (guard) to put back a character in a streambuf 00115 * whenever an exception or an eof occur. 00116 */ 00117 template <class _CharT, class _Traits> 00118 struct _SPutBackC { 00119 typedef basic_streambuf<_CharT, _Traits> _StreamBuf; 00120 typedef typename _StreamBuf::int_type int_type; 00121 _SPutBackC(_StreamBuf *pfrom) 00122 : __pfrom(pfrom), __c(0), __do_guard(false) {} 00123 ~_SPutBackC() { 00124 if (__do_guard) { 00125 __pfrom->sputbackc(_Traits::to_char_type(__c)); 00126 } 00127 } 00128 00129 void guard(int_type c) { 00130 __c = c; 00131 __do_guard = true; 00132 } 00133 void release() { 00134 __do_guard = false; 00135 } 00136 00137 private: 00138 _StreamBuf *__pfrom; 00139 int_type __c; 00140 bool __do_guard; 00141 }; 00142 00143 template <class _CharT, class _Traits> 00144 bool basic_ostream<_CharT, _Traits> 00145 ::_M_copy_unbuffered(basic_streambuf<_CharT, _Traits>* __from, 00146 basic_streambuf<_CharT, _Traits>* __to) { 00147 typedef _SPutBackC<_CharT, _Traits> _SPutBackCGuard; 00148 bool __any_inserted = false; 00149 int_type __c; 00150 00151 _STLP_TRY { 00152 _SPutBackCGuard __cguard(__from); 00153 for (;;) { 00154 _STLP_TRY { 00155 __c = __from->sbumpc(); 00156 } 00157 _STLP_CATCH_ALL { 00158 this->_M_handle_exception(ios_base::failbit); 00159 break; 00160 } 00161 00162 if (this->_S_eof(__c)) 00163 break; 00164 00165 __cguard.guard(__c); 00166 #if defined (__DMC__) 00167 _STLP_TRY { 00168 #endif 00169 if (this->_S_eof(__to->sputc(_Traits::to_char_type(__c)))) 00170 break; 00171 00172 #if defined (__DMC__) 00173 } 00174 _STLP_CATCH_ALL { 00175 this->_M_handle_exception(ios_base::badbit); 00176 break; 00177 } 00178 #endif 00179 __cguard.release(); 00180 __any_inserted = true; 00181 } 00182 } 00183 _STLP_CATCH_ALL { 00184 this->_M_handle_exception(ios_base::badbit); 00185 } 00186 return __any_inserted; 00187 } 00188 00189 _STLP_MOVE_TO_PRIV_NAMESPACE 00190 00191 // Helper function for numeric output. 00192 template <class _CharT, class _Traits, class _Number> 00193 basic_ostream<_CharT, _Traits>& _STLP_CALL 00194 __put_num(basic_ostream<_CharT, _Traits>& __os, _Number __x) { 00195 typedef typename basic_ostream<_CharT, _Traits>::sentry _Sentry; 00196 _Sentry __sentry(__os); 00197 bool __failed = true; 00198 00199 if (__sentry) { 00200 _STLP_TRY { 00201 typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > _NumPut; 00202 __failed = (use_facet<_NumPut>(__os.getloc())).put(ostreambuf_iterator<_CharT, _Traits>(__os.rdbuf()), 00203 __os, __os.fill(), 00204 __x).failed(); 00205 } 00206 _STLP_CATCH_ALL { 00207 __os._M_handle_exception(ios_base::badbit); 00208 } 00209 } 00210 if (__failed) 00211 __os.setstate(ios_base::badbit); 00212 return __os; 00213 } 00214 00215 _STLP_MOVE_TO_STD_NAMESPACE 00216 00217 /* 00218 * In the following operators we try to limit code bloat by limiting the 00219 * number of __put_num instanciations. 00220 */ 00221 template <class _CharT, class _Traits> 00222 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(short __x) { 00223 _STLP_STATIC_ASSERT( sizeof(short) <= sizeof(long) ) 00224 long __tmp = ((this->flags() & _Basic_ios::basefield) != ios_base::dec) ? 00225 __STATIC_CAST(long, __STATIC_CAST(unsigned short, __x)): __x; 00226 return _STLP_PRIV __put_num(*this, __tmp); 00227 } 00228 00229 template <class _CharT, class _Traits> 00230 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned short __x) { 00231 _STLP_STATIC_ASSERT( sizeof(unsigned short) <= sizeof(unsigned long) ) 00232 return _STLP_PRIV __put_num(*this, __STATIC_CAST(unsigned long,__x)); 00233 } 00234 00235 template <class _CharT, class _Traits> 00236 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(int __x) { 00237 _STLP_STATIC_ASSERT( sizeof(int) <= sizeof(long) ) 00238 long __tmp = ((this->flags() & _Basic_ios::basefield) != ios_base::dec) ? 00239 __STATIC_CAST(long, __STATIC_CAST(unsigned int, __x)): __x; 00240 return _STLP_PRIV __put_num(*this, __tmp); 00241 } 00242 00243 template <class _CharT, class _Traits> 00244 #if defined (_WIN64) || !defined (_STLP_MSVC) || (_STLP_MSVC < 1300) 00245 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned int __x) { 00246 _STLP_STATIC_ASSERT( sizeof(unsigned int) <= sizeof(unsigned long) ) 00247 #else 00248 /* We define this operator with size_t rather than unsigned int to avoid 00249 * 64 bits warning. 00250 */ 00251 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(size_t __x) { 00252 _STLP_STATIC_ASSERT( sizeof(size_t) <= sizeof(unsigned long) ) 00253 #endif 00254 return _STLP_PRIV __put_num(*this, __STATIC_CAST(unsigned long,__x)); 00255 } 00256 00257 template <class _CharT, class _Traits> 00258 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __x) 00259 { return _STLP_PRIV __put_num(*this, __x); } 00260 00261 template <class _CharT, class _Traits> 00262 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __x) 00263 { return _STLP_PRIV __put_num(*this, __x); } 00264 00265 #ifdef _STLP_LONG_LONG 00266 template <class _CharT, class _Traits> 00267 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (_STLP_LONG_LONG __x) 00268 { return _STLP_PRIV __put_num(*this, __x); } 00269 00270 template <class _CharT, class _Traits> 00271 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (unsigned _STLP_LONG_LONG __x) 00272 { return _STLP_PRIV __put_num(*this, __x); } 00273 #endif 00274 00275 template <class _CharT, class _Traits> 00276 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __x) 00277 { return _STLP_PRIV __put_num(*this, __STATIC_CAST(double,__x)); } 00278 00279 template <class _CharT, class _Traits> 00280 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __x) 00281 { return _STLP_PRIV __put_num(*this, __x); } 00282 00283 #ifndef _STLP_NO_LONG_DOUBLE 00284 template <class _CharT, class _Traits> 00285 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __x) 00286 { return _STLP_PRIV __put_num(*this, __x); } 00287 #endif 00288 00289 template <class _CharT, class _Traits> 00290 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __x) 00291 { return _STLP_PRIV __put_num(*this, __x); } 00292 00293 #ifndef _STLP_NO_BOOL 00294 template <class _CharT, class _Traits> 00295 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __x) 00296 { return _STLP_PRIV __put_num(*this, __x); } 00297 #endif 00298 00299 template <class _CharT, class _Traits> 00300 void basic_ostream<_CharT, _Traits>::_M_put_char(_CharT __c) { 00301 sentry __sentry(*this); 00302 if (__sentry) { 00303 bool __failed = true; 00304 _STLP_TRY { 00305 streamsize __npad = this->width() > 0 ? this->width() - 1 : 0; 00306 // if (__npad <= 1) 00307 if (__npad == 0) 00308 __failed = this->_S_eof(this->rdbuf()->sputc(__c)); 00309 else if ((this->flags() & ios_base::adjustfield) == ios_base::left) { 00310 __failed = this->_S_eof(this->rdbuf()->sputc(__c)); 00311 __failed = __failed || 00312 this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; 00313 } 00314 else { 00315 __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; 00316 __failed = __failed || this->_S_eof(this->rdbuf()->sputc(__c)); 00317 } 00318 00319 this->width(0); 00320 } 00321 _STLP_CATCH_ALL { 00322 this->_M_handle_exception(ios_base::badbit); 00323 } 00324 00325 if (__failed) 00326 this->setstate(ios_base::badbit); 00327 } 00328 } 00329 00330 template <class _CharT, class _Traits> 00331 void basic_ostream<_CharT, _Traits>::_M_put_nowiden(const _CharT* __s) { 00332 sentry __sentry(*this); 00333 if (__sentry) { 00334 bool __failed = true; 00335 streamsize __n = _Traits::length(__s); 00336 streamsize __npad = this->width() > __n ? this->width() - __n : 0; 00337 00338 _STLP_TRY { 00339 if (__npad == 0) 00340 __failed = this->rdbuf()->sputn(__s, __n) != __n; 00341 else if ((this->flags() & ios_base::adjustfield) == ios_base::left) { 00342 __failed = this->rdbuf()->sputn(__s, __n) != __n; 00343 __failed = __failed || 00344 this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; 00345 } 00346 else { 00347 __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; 00348 __failed = __failed || this->rdbuf()->sputn(__s, __n) != __n; 00349 } 00350 00351 this->width(0); 00352 } 00353 _STLP_CATCH_ALL { 00354 this->_M_handle_exception(ios_base::badbit); 00355 } 00356 00357 if (__failed) 00358 this->setstate(ios_base::failbit); 00359 } 00360 } 00361 00362 template <class _CharT, class _Traits> 00363 void basic_ostream<_CharT, _Traits>::_M_put_widen(const char* __s) { 00364 sentry __sentry(*this); 00365 if (__sentry) { 00366 bool __failed = true; 00367 streamsize __n = char_traits<char>::length(__s); 00368 streamsize __npad = this->width() > __n ? this->width() - __n : 0; 00369 00370 _STLP_TRY { 00371 if (__npad == 0) 00372 __failed = !this->_M_put_widen_aux(__s, __n); 00373 else if ((this->flags() & ios_base::adjustfield) == ios_base::left) { 00374 __failed = !this->_M_put_widen_aux(__s, __n); 00375 __failed = __failed || 00376 this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; 00377 } 00378 else { 00379 __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; 00380 __failed = __failed || !this->_M_put_widen_aux(__s, __n); 00381 } 00382 00383 this->width(0); 00384 } 00385 _STLP_CATCH_ALL { 00386 this->_M_handle_exception(ios_base::badbit); 00387 } 00388 00389 if (__failed) 00390 this->setstate(ios_base::failbit); 00391 } 00392 } 00393 00394 template <class _CharT, class _Traits> 00395 bool basic_ostream<_CharT, _Traits>::_M_put_widen_aux(const char* __s, 00396 streamsize __n) { 00397 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00398 00399 for ( ; __n > 0 ; --__n) 00400 if (this->_S_eof(__buf->sputc(this->widen(*__s++)))) 00401 return false; 00402 return true; 00403 } 00404 00405 // Unformatted output of a single character. 00406 template <class _CharT, class _Traits> 00407 basic_ostream<_CharT, _Traits>& 00408 basic_ostream<_CharT, _Traits>::put(char_type __c) { 00409 sentry __sentry(*this); 00410 bool __failed = true; 00411 00412 if (__sentry) { 00413 _STLP_TRY { 00414 __failed = this->_S_eof(this->rdbuf()->sputc(__c)); 00415 } 00416 _STLP_CATCH_ALL { 00417 this->_M_handle_exception(ios_base::badbit); 00418 } 00419 } 00420 00421 if (__failed) 00422 this->setstate(ios_base::badbit); 00423 00424 return *this; 00425 } 00426 00427 // Unformatted output of a single character. 00428 template <class _CharT, class _Traits> 00429 basic_ostream<_CharT, _Traits>& 00430 basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n) { 00431 sentry __sentry(*this); 00432 bool __failed = true; 00433 00434 if (__sentry) { 00435 _STLP_TRY { 00436 __failed = this->rdbuf()->sputn(__s, __n) != __n; 00437 } 00438 _STLP_CATCH_ALL { 00439 this->_M_handle_exception(ios_base::badbit); 00440 } 00441 } 00442 00443 if (__failed) 00444 this->setstate(ios_base::badbit); 00445 00446 return *this; 00447 } 00448 00449 _STLP_END_NAMESPACE 00450 00451 #endif /* _STLP_OSTREAM_C */ 00452 00453 // Local Variables: 00454 // mode:C++ 00455 // End: Generated on Sat May 26 2012 04:27:56 for ReactOS by
1.7.6.1
|