Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_sstream.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 00019 #ifndef _STLP_SSTREAM_C 00020 #define _STLP_SSTREAM_C 00021 00022 #ifndef _STLP_INTERNAL_SSTREAM 00023 # include <stl/_sstream.h> 00024 #endif 00025 00026 #if defined ( _STLP_NESTED_TYPE_PARAM_BUG ) 00027 // no wint_t is supported for this mode 00028 # define __BSB_int_type__ int 00029 # define __BSB_pos_type__ streampos 00030 #else 00031 # define __BSB_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 00032 # define __BSB_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type 00033 #endif 00034 00035 _STLP_BEGIN_NAMESPACE 00036 00037 //---------------------------------------------------------------------- 00038 // Non-inline stringbuf member functions. 00039 00040 // Constructors. Note that the base class constructor sets all of the 00041 // get and area pointers to null. 00042 00043 template <class _CharT, class _Traits, class _Alloc> 00044 basic_stringbuf<_CharT, _Traits, _Alloc> 00045 ::basic_stringbuf(ios_base::openmode __mode) 00046 : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str() 00047 {} 00048 00049 template <class _CharT, class _Traits, class _Alloc> 00050 basic_stringbuf<_CharT, _Traits, _Alloc> 00051 ::basic_stringbuf(const basic_string<_CharT, _Traits, _Alloc>& __s, ios_base::openmode __mode) 00052 : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str(__s) 00053 { 00054 _M_set_ptrs(); 00055 } 00056 00057 template <class _CharT, class _Traits, class _Alloc> 00058 basic_stringbuf<_CharT, _Traits, _Alloc>::~basic_stringbuf() 00059 {} 00060 00061 // Set the underlying string to a new value. 00062 template <class _CharT, class _Traits, class _Alloc> 00063 void 00064 basic_stringbuf<_CharT, _Traits, _Alloc>::str(const basic_string<_CharT, _Traits, _Alloc>& __s) 00065 { 00066 _M_str = __s; 00067 _M_set_ptrs(); 00068 } 00069 00070 template <class _CharT, class _Traits, class _Alloc> 00071 void 00072 basic_stringbuf<_CharT, _Traits, _Alloc>::_M_set_ptrs() 00073 { 00074 _CharT* __data_ptr = _S_start(_M_str); 00075 _CharT* __data_end = _S_finish(_M_str); 00076 // The initial read position is the beginning of the string. 00077 if (_M_mode & ios_base::in) { 00078 this->setg(__data_ptr, (_M_mode & ios_base::ate) ? __data_end : __data_ptr, __data_end); 00079 } 00080 00081 // The initial write position is the beginning of the string. 00082 if (_M_mode & ios_base::out) { 00083 if ( _M_mode & (ios_base::app | ios_base::ate) ) { 00084 this->setp( __data_end, __data_end ); 00085 } else { 00086 this->setp( __data_ptr, __data_end ); 00087 this->pbump((int)_M_str.size()); // initial write position, if we initialized with string 00088 } 00089 // this->setp((_M_mode & (ios_base::app | ios_base::ate))? __data_end : __data_ptr, __data_end); 00090 } 00091 } 00092 00093 // Precondition: gptr() >= egptr(). Returns a character, if one is available. 00094 template <class _CharT, class _Traits, class _Alloc> 00095 __BSB_int_type__ 00096 basic_stringbuf<_CharT, _Traits, _Alloc>::underflow() { 00097 return this->gptr() != this->egptr() 00098 ? _Traits::to_int_type(*this->gptr()) 00099 : _Traits::eof(); 00100 } 00101 00102 // Precondition: gptr() >= egptr(). 00103 template <class _CharT, class _Traits, class _Alloc> 00104 __BSB_int_type__ 00105 basic_stringbuf<_CharT, _Traits, _Alloc>::uflow() { 00106 if (this->gptr() != this->egptr()) { 00107 int_type __c = _Traits::to_int_type(*this->gptr()); 00108 this->gbump(1); 00109 return __c; 00110 } 00111 else 00112 return _Traits::eof(); 00113 } 00114 00115 template <class _CharT, class _Traits, class _Alloc> 00116 __BSB_int_type__ 00117 basic_stringbuf<_CharT, _Traits, _Alloc>::pbackfail(int_type __c) { 00118 if (this->gptr() != this->eback()) { 00119 if (!_Traits::eq_int_type(__c, _Traits::eof())) { 00120 if (_Traits::eq(_Traits::to_char_type(__c), this->gptr()[-1])) { 00121 this->gbump(-1); 00122 return __c; 00123 } 00124 else if (_M_mode & ios_base::out) { 00125 this->gbump(-1); 00126 *this->gptr() = _Traits::to_char_type(__c); 00127 return __c; 00128 } 00129 else 00130 return _Traits::eof(); 00131 } 00132 else { 00133 this->gbump(-1); 00134 return _Traits::not_eof(__c); 00135 } 00136 } 00137 else 00138 return _Traits::eof(); 00139 } 00140 00141 template <class _CharT, class _Traits, class _Alloc> 00142 __BSB_int_type__ basic_stringbuf<_CharT, _Traits, _Alloc>::overflow(int_type __c) 00143 { 00144 if (!_Traits::eq_int_type(__c, _Traits::eof())) { 00145 if (_M_mode & ios_base::out) { 00146 if ( this->pptr() < this->epptr() ) { // just put back in any case 00147 _M_str.push_back( _Traits::to_char_type(__c) ); 00148 this->pbump(1); 00149 } else if ( _M_mode & ios_base::in ) { 00150 ptrdiff_t __offset = this->gptr() - this->eback(); 00151 _M_str.push_back(_Traits::to_char_type(__c)); 00152 _CharT* __data_ptr = _S_start(_M_str); 00153 this->setg(__data_ptr, __data_ptr + __offset, _S_finish(_M_str)); 00154 this->setp(__data_ptr, _S_finish(_M_str)); 00155 this->pbump((int)_M_str.size()); 00156 } else { 00157 _M_str.push_back( _Traits::to_char_type(__c) ); 00158 this->setp(_S_start(_M_str), _S_finish(_M_str)); 00159 this->pbump((int)_M_str.size()); 00160 } 00161 return __c; 00162 } 00163 return _Traits::eof(); // Overflow always fails if it's read-only 00164 } 00165 return _Traits::not_eof(__c); // __c is EOF, so we don't have to do anything 00166 } 00167 00168 template <class _CharT, class _Traits, class _Alloc> 00169 streamsize 00170 basic_stringbuf<_CharT, _Traits, _Alloc>::xsputn(const char_type* __s, 00171 streamsize __n) { 00172 streamsize __nwritten = 0; 00173 00174 if ((_M_mode & ios_base::out) && __n > 0) { 00175 // If the put pointer is somewhere in the middle of the string, 00176 // then overwrite instead of append. 00177 if ( !_M_str.empty() && this->pbase() == _S_start(_M_str)) { 00178 ptrdiff_t __avail = _S_finish(_M_str) - this->pptr(); 00179 if (__avail > __n) { 00180 _Traits::copy(this->pptr(), __s, __STATIC_CAST(size_t, __n)); 00181 this->pbump((int)__n); 00182 return __n; 00183 } else { 00184 _Traits::copy(this->pptr(), __s, __avail); 00185 __nwritten += __avail; 00186 __n -= __avail; 00187 __s += __avail; 00188 } 00189 } 00190 00191 // At this point we know we're appending. 00192 _CharT* __data_ptr; 00193 if (_M_mode & ios_base::in) { 00194 ptrdiff_t __get_offset = this->gptr() - this->eback(); 00195 _M_str.append(__s, __s + __STATIC_CAST(ptrdiff_t, __n)); 00196 __data_ptr = _S_start(_M_str); 00197 this->setg(__data_ptr, __data_ptr + __get_offset, _S_finish(_M_str)); 00198 } else { 00199 _M_str.append(__s, __s + __STATIC_CAST(ptrdiff_t, __n)); 00200 __data_ptr = _S_start(_M_str); 00201 } 00202 00203 this->setp(__data_ptr, _S_finish(_M_str)); 00204 this->pbump((int)_M_str.size()); 00205 __nwritten += __n; 00206 } 00207 00208 return __nwritten; 00209 } 00210 00211 template <class _CharT, class _Traits, class _Alloc> 00212 streamsize 00213 basic_stringbuf<_CharT, _Traits, _Alloc>::_M_xsputnc(char_type __c, 00214 streamsize __n) { 00215 streamsize __nwritten = 0; 00216 00217 if ((_M_mode & ios_base::out) && __n > 0) { 00218 // If the put pointer is somewhere in the middle of the string, 00219 // then overwrite instead of append. 00220 if (this->pbase() == _S_start(_M_str)) { 00221 ptrdiff_t __avail = _S_finish(_M_str) - this->pptr(); 00222 if (__avail > __n) { 00223 _Traits::assign(this->pptr(), __STATIC_CAST(size_t, __n), __c); 00224 this->pbump(__STATIC_CAST(int, __n)); 00225 return __n; 00226 } 00227 else { 00228 _Traits::assign(this->pptr(), __avail, __c); 00229 __nwritten += __avail; 00230 __n -= __avail; 00231 } 00232 } 00233 00234 // At this point we know we're appending. 00235 size_t __app_size = sizeof(streamsize) > sizeof(size_t) ? __STATIC_CAST(size_t, (min)(__n, __STATIC_CAST(streamsize, _M_str.max_size()))) 00236 : __STATIC_CAST(size_t, __n); 00237 _CharT* __data_ptr; 00238 if (this->_M_mode & ios_base::in) { 00239 ptrdiff_t __get_offset = this->gptr() - this->eback(); 00240 _M_str.append(__app_size, __c); 00241 __data_ptr = _S_start(_M_str); 00242 this->setg(__data_ptr, __data_ptr + __get_offset, _S_finish(_M_str)); 00243 } else { 00244 _M_str.append(__app_size, __c); 00245 __data_ptr = _S_start(_M_str); 00246 } 00247 00248 this->setp(__data_ptr, _S_finish(_M_str)); 00249 this->pbump((int)_M_str.size()); 00250 __nwritten += __app_size; 00251 } 00252 00253 return __nwritten; 00254 } 00255 00256 // According to the C++ standard the effects of setbuf are implementation 00257 // defined, except that setbuf(0, 0) has no effect. In this implementation, 00258 // setbuf(<anything>, n), for n > 0, calls reserve(n) on the underlying 00259 // string. 00260 template <class _CharT, class _Traits, class _Alloc> 00261 basic_streambuf<_CharT, _Traits>* 00262 basic_stringbuf<_CharT, _Traits, _Alloc>::setbuf(_CharT*, streamsize __n) { 00263 if (__n > 0) { 00264 bool __do_get_area = false; 00265 bool __do_put_area = false; 00266 ptrdiff_t __offg = 0; 00267 ptrdiff_t __offp = 0; 00268 00269 if (this->pbase() == _S_start(_M_str)) { 00270 __do_put_area = true; 00271 __offp = this->pptr() - this->pbase(); 00272 } 00273 00274 if (this->eback() == _S_start(_M_str)) { 00275 __do_get_area = true; 00276 __offg = this->gptr() - this->eback(); 00277 } 00278 00279 _M_str.reserve(sizeof(streamsize) > sizeof(size_t) ? __STATIC_CAST(size_t, (min)(__n, __STATIC_CAST(streamsize, _M_str.max_size()))) 00280 : __STATIC_CAST(size_t, __n)); 00281 00282 _CharT* __data_ptr = _S_start(_M_str); 00283 00284 if (__do_get_area) { 00285 this->setg(__data_ptr, __data_ptr + __offg, _S_finish(_M_str)); 00286 } 00287 00288 if (__do_put_area) { 00289 this->setp(__data_ptr, _S_finish(_M_str)); 00290 this->pbump((int)__offp); 00291 } 00292 } 00293 00294 return this; 00295 } 00296 00297 template <class _CharT, class _Traits, class _Alloc> 00298 __BSB_pos_type__ 00299 basic_stringbuf<_CharT, _Traits, _Alloc> 00300 ::seekoff(off_type __off, 00301 ios_base::seekdir __dir, 00302 ios_base::openmode __mode) { 00303 __mode &= _M_mode; 00304 00305 bool __imode = (__mode & ios_base::in) != 0; 00306 bool __omode = (__mode & ios_base::out) != 0; 00307 00308 if ( !(__imode || __omode) ) 00309 return pos_type(off_type(-1)); 00310 00311 if ( (__imode && (this->gptr() == 0)) || (__omode && (this->pptr() == 0)) ) 00312 return pos_type(off_type(-1)); 00313 00314 streamoff __newoff; 00315 switch(__dir) { 00316 case ios_base::beg: 00317 __newoff = 0; 00318 break; 00319 case ios_base::end: 00320 __newoff = _M_str.size(); 00321 break; 00322 case ios_base::cur: 00323 __newoff = __imode ? this->gptr() - this->eback() : this->pptr() - this->pbase(); 00324 if ( __off == 0 ) { 00325 return pos_type(__newoff); 00326 } 00327 break; 00328 default: 00329 return pos_type(off_type(-1)); 00330 } 00331 00332 __off += __newoff; 00333 00334 if (__imode) { 00335 ptrdiff_t __n = this->egptr() - this->eback(); 00336 00337 if (__off < 0 || __off > __n) 00338 return pos_type(off_type(-1)); 00339 this->setg(this->eback(), this->eback() + __STATIC_CAST(ptrdiff_t, __off), 00340 this->eback() + __STATIC_CAST(ptrdiff_t, __n)); 00341 } 00342 00343 if (__omode) { 00344 ptrdiff_t __n = this->epptr() - this->pbase(); 00345 00346 if (__off < 0 || __off > __n) 00347 return pos_type(off_type(-1)); 00348 this->setp(this->pbase(), this->pbase() + __n); 00349 this->pbump((int)__off); 00350 } 00351 00352 return pos_type(__off); 00353 } 00354 00355 template <class _CharT, class _Traits, class _Alloc> 00356 __BSB_pos_type__ 00357 basic_stringbuf<_CharT, _Traits, _Alloc> 00358 ::seekpos(pos_type __pos, ios_base::openmode __mode) { 00359 __mode &= _M_mode; 00360 00361 bool __imode = (__mode & ios_base::in) != 0; 00362 bool __omode = (__mode & ios_base::out) != 0; 00363 00364 if ( !(__imode || __omode) ) 00365 return pos_type(off_type(-1)); 00366 00367 if ( (__imode && (this->gptr() == 0)) || (__omode && (this->pptr() == 0)) ) 00368 return pos_type(off_type(-1)); 00369 00370 const off_type __n = __pos - pos_type(off_type(0)); 00371 00372 if (__imode) { 00373 if (__n < 0 || __n > this->egptr() - this->eback()) 00374 return pos_type(off_type(-1)); 00375 this->setg(this->eback(), this->eback() + __STATIC_CAST(ptrdiff_t, __n), this->egptr()); 00376 } 00377 00378 if (__omode) { 00379 if (__n < 0 || size_t(__n) > _M_str.size()) 00380 return pos_type(off_type(-1)); 00381 00382 this->setp(_S_start(_M_str), _S_finish(_M_str)); 00383 this->pbump((int)__n); 00384 } 00385 00386 return __pos; 00387 } 00388 00389 //---------------------------------------------------------------------- 00390 // Non-inline istringstream member functions. 00391 00392 template <class _CharT, class _Traits, class _Alloc> 00393 basic_istringstream<_CharT, _Traits, _Alloc> 00394 ::basic_istringstream(ios_base::openmode __mode) 00395 : basic_istream<_CharT, _Traits>(0), 00396 _M_buf(__mode | ios_base::in) { 00397 this->init(&_M_buf); 00398 } 00399 00400 template <class _CharT, class _Traits, class _Alloc> 00401 basic_istringstream<_CharT, _Traits, _Alloc> 00402 ::basic_istringstream(const _String& __str,ios_base::openmode __mode) 00403 : basic_istream<_CharT, _Traits>(0), 00404 _M_buf(__str, __mode | ios_base::in) { 00405 this->init(&_M_buf); 00406 } 00407 00408 template <class _CharT, class _Traits, class _Alloc> 00409 basic_istringstream<_CharT, _Traits, _Alloc>::~basic_istringstream() 00410 {} 00411 00412 //---------------------------------------------------------------------- 00413 // Non-inline ostringstream member functions. 00414 00415 template <class _CharT, class _Traits, class _Alloc> 00416 basic_ostringstream<_CharT, _Traits, _Alloc> 00417 ::basic_ostringstream(ios_base::openmode __mode) 00418 : basic_ostream<_CharT, _Traits>(0), 00419 _M_buf(__mode | ios_base::out) { 00420 this->init(&_M_buf); 00421 } 00422 00423 template <class _CharT, class _Traits, class _Alloc> 00424 basic_ostringstream<_CharT, _Traits, _Alloc> 00425 ::basic_ostringstream(const _String& __str, ios_base::openmode __mode) 00426 : basic_ostream<_CharT, _Traits>(0), 00427 _M_buf(__str, __mode | ios_base::out) { 00428 this->init(&_M_buf); 00429 } 00430 00431 template <class _CharT, class _Traits, class _Alloc> 00432 basic_ostringstream<_CharT, _Traits, _Alloc>::~basic_ostringstream() 00433 {} 00434 00435 //---------------------------------------------------------------------- 00436 // Non-inline stringstream member functions. 00437 00438 template <class _CharT, class _Traits, class _Alloc> 00439 basic_stringstream<_CharT, _Traits, _Alloc> 00440 ::basic_stringstream(ios_base::openmode __mode) 00441 : basic_iostream<_CharT, _Traits>(0), _M_buf(__mode) { 00442 this->init(&_M_buf); 00443 } 00444 00445 template <class _CharT, class _Traits, class _Alloc> 00446 basic_stringstream<_CharT, _Traits, _Alloc> 00447 ::basic_stringstream(const _String& __str, ios_base::openmode __mode) 00448 : basic_iostream<_CharT, _Traits>(0), _M_buf(__str, __mode) { 00449 this->init(&_M_buf); 00450 } 00451 00452 template <class _CharT, class _Traits, class _Alloc> 00453 basic_stringstream<_CharT, _Traits, _Alloc>::~basic_stringstream() 00454 {} 00455 00456 _STLP_END_NAMESPACE 00457 00458 # undef __BSB_int_type__ 00459 # undef __BSB_pos_type__ 00460 00461 #endif /* _STLP_SSTREAM_C */ 00462 00463 // Local Variables: 00464 // mode:C++ 00465 // End: Generated on Sun May 27 2012 04:29:31 for ReactOS by
1.7.6.1
|