epoc32/include/stdapis/stlportv5/stl/_sstream.c
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
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 
    19 #ifndef _STLP_SSTREAM_C
    20 #define _STLP_SSTREAM_C
    21 
    22 #ifndef _STLP_INTERNAL_SSTREAM
    23 #  include <stl/_sstream.h>
    24 #endif
    25 
    26 #if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
    27 // no wint_t is supported for this mode
    28 #  define __BSB_int_type__ int
    29 #  define __BSB_pos_type__ streampos
    30 #else
    31 #  define __BSB_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
    32 #  define __BSB_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
    33 #endif
    34 
    35 _STLP_BEGIN_NAMESPACE
    36 
    37 //----------------------------------------------------------------------
    38 // Non-inline stringbuf member functions.
    39 
    40 // Constructors.  Note that the base class constructor sets all of the
    41 // get and area pointers to null.
    42 
    43 template <class _CharT, class _Traits, class _Alloc>
    44 basic_stringbuf<_CharT, _Traits, _Alloc>
    45   ::basic_stringbuf(ios_base::openmode __mode)
    46     : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str()
    47 {}
    48 
    49 template <class _CharT, class _Traits, class _Alloc>
    50 basic_stringbuf<_CharT, _Traits, _Alloc>
    51   ::basic_stringbuf(const basic_string<_CharT, _Traits, _Alloc>& __s, ios_base::openmode __mode)
    52     : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str(__s)
    53 {
    54   _M_set_ptrs();
    55 }
    56 
    57 template <class _CharT, class _Traits, class _Alloc>
    58 basic_stringbuf<_CharT, _Traits, _Alloc>::~basic_stringbuf()
    59 {}
    60 
    61 // Set the underlying string to a new value.
    62 template <class _CharT, class _Traits, class _Alloc>
    63 void
    64 basic_stringbuf<_CharT, _Traits, _Alloc>::str(const basic_string<_CharT, _Traits, _Alloc>& __s)
    65 {
    66   _M_str = __s;
    67   _M_set_ptrs();
    68 }
    69 
    70 template <class _CharT, class _Traits, class _Alloc>
    71 void
    72 basic_stringbuf<_CharT, _Traits, _Alloc>::_M_set_ptrs() {
    73   _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data());
    74   _CharT* __data_end = __data_ptr + _M_str.size();
    75   // The initial read position is the beginning of the string.
    76   if (_M_mode & ios_base::in) {
    77     if (_M_mode & ios_base::ate)
    78       this->setg(__data_ptr, __data_end, __data_end);
    79     else
    80       this->setg(__data_ptr, __data_ptr, __data_end);
    81   }
    82 
    83   // The initial write position is the beginning of the string.
    84   if (_M_mode & ios_base::out) {
    85     if (_M_mode & (ios_base::app | ios_base::ate))
    86       this->setp(__data_end, __data_end);
    87     else
    88       this->setp(__data_ptr, __data_end);
    89   }
    90 }
    91 
    92 // Precondition: gptr() >= egptr().  Returns a character, if one is available.
    93 template <class _CharT, class _Traits, class _Alloc>
    94 __BSB_int_type__
    95 basic_stringbuf<_CharT, _Traits, _Alloc>::underflow() {
    96   return this->gptr() != this->egptr()
    97     ? _Traits::to_int_type(*this->gptr())
    98     : _Traits::eof();
    99 }
   100 
   101 // Precondition: gptr() >= egptr().
   102 template <class _CharT, class _Traits, class _Alloc>
   103 __BSB_int_type__
   104 basic_stringbuf<_CharT, _Traits, _Alloc>::uflow() {
   105   if (this->gptr() != this->egptr()) {
   106     int_type __c = _Traits::to_int_type(*this->gptr());
   107     this->gbump(1);
   108     return __c;
   109   }
   110   else
   111     return _Traits::eof();
   112 }
   113 
   114 template <class _CharT, class _Traits, class _Alloc>
   115 __BSB_int_type__
   116 basic_stringbuf<_CharT, _Traits, _Alloc>::pbackfail(int_type __c) {
   117   if (this->gptr() != this->eback()) {
   118     if (!_Traits::eq_int_type(__c, _Traits::eof())) {
   119       if (_Traits::eq(_Traits::to_char_type(__c), this->gptr()[-1])) {
   120         this->gbump(-1);
   121         return __c;
   122       }
   123       else if (_M_mode & ios_base::out) {
   124         this->gbump(-1);
   125         *this->gptr() = _Traits::to_char_type(__c);
   126         return __c;
   127       }
   128       else
   129         return _Traits::eof();
   130     }
   131     else {
   132       this->gbump(-1);
   133       return _Traits::not_eof(__c);
   134     }
   135   }
   136   else
   137     return _Traits::eof();
   138 }
   139 
   140 template <class _CharT, class _Traits, class _Alloc>
   141 __BSB_int_type__
   142 basic_stringbuf<_CharT, _Traits, _Alloc>::overflow(int_type __c) {
   143   // fbp : reverse order of "ifs" to pass Dietmar's test.
   144   // Apparently, standard allows overflow with eof even for read-only streams.
   145   if (!_Traits::eq_int_type(__c, _Traits::eof())) {
   146     if (_M_mode & ios_base::out) {
   147       if (!(_M_mode & ios_base::in)) {
   148         // It's a write-only streambuf, so we can use special append buffer.
   149         if (this->pptr() == this->epptr())
   150           this->_M_append_buffer();
   151 
   152         if (this->pptr() != this->epptr()) {
   153           *this->pptr() = _Traits::to_char_type(__c);
   154           this->pbump(1);
   155           return __c;
   156         }
   157         else
   158           return _Traits::eof();
   159       }
   160       else {
   161         // We're not using a special append buffer, just the string itself.
   162         if (this->pptr() == this->epptr()) {
   163           ptrdiff_t __offset = this->gptr() - this->eback();
   164           _M_str.push_back(_Traits::to_char_type(__c));
   165 
   166           _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data());
   167           size_t __data_size = _M_str.size();
   168 
   169           this->setg(__data_ptr, __data_ptr + __offset, __data_ptr+__data_size);
   170           this->setp(__data_ptr, __data_ptr + __data_size);
   171           this->pbump((int)__data_size);
   172           return __c;
   173         }
   174         else {
   175           *this->pptr() = _Traits::to_char_type(__c);
   176           this->pbump(1);
   177           return __c;
   178         }
   179       }
   180     }
   181     else                          // Overflow always fails if it's read-only
   182       return _Traits::eof();
   183   }
   184   else                        // __c is EOF, so we don't have to do anything
   185     return _Traits::not_eof(__c);
   186 }
   187 
   188 template <class _CharT, class _Traits, class _Alloc>
   189 streamsize
   190 basic_stringbuf<_CharT, _Traits, _Alloc>::xsputn(const char_type* __s,
   191                                                  streamsize __n) {
   192   streamsize __nwritten = 0;
   193 
   194   if ((_M_mode & ios_base::out) && __n > 0) {
   195     // If the put pointer is somewhere in the middle of the string,
   196     // then overwrite instead of append.
   197     if (this->pbase() == _M_str.data() ) {
   198       ptrdiff_t __avail = _M_str.data() + _M_str.size() - this->pptr();
   199       if (__avail > __n) {
   200         _Traits::copy(this->pptr(), __s, __STATIC_CAST(size_t, __n));
   201         this->pbump((int)__n);
   202         return __n;
   203       }
   204       else {
   205         _Traits::copy(this->pptr(), __s, __avail);
   206         __nwritten += __avail;
   207         __n -= __avail;
   208         __s += __avail;
   209         this->setp(_M_Buf, _M_Buf + __STATIC_CAST(int,_S_BufSiz));
   210       }
   211     }
   212 
   213     // At this point we know we're appending.
   214     if (_M_mode & ios_base::in) {
   215       ptrdiff_t __get_offset = this->gptr() - this->eback();
   216       _M_str.append(__s, __s + __STATIC_CAST(ptrdiff_t, __n));
   217 
   218       _CharT* __data_ptr = __CONST_CAST(_CharT*, _M_str.data());
   219       size_t __data_size = _M_str.size();
   220 
   221       this->setg(__data_ptr, __data_ptr + __get_offset, __data_ptr + __data_size);
   222       this->setp(__data_ptr, __data_ptr + __data_size);
   223       this->pbump((int)__data_size);
   224     }
   225     else {
   226       _M_append_buffer();
   227       _M_str.append(__s, __s + __STATIC_CAST(ptrdiff_t, __n));
   228     }
   229 
   230     __nwritten += __n;
   231   }
   232 
   233   return __nwritten;
   234 }
   235 
   236 template <class _CharT, class _Traits, class _Alloc>
   237 streamsize
   238 basic_stringbuf<_CharT, _Traits, _Alloc>::_M_xsputnc(char_type __c,
   239                                                      streamsize __n) {
   240   streamsize __nwritten = 0;
   241 
   242   if ((_M_mode & ios_base::out) && __n > 0) {
   243     // If the put pointer is somewhere in the middle of the string,
   244     // then overwrite instead of append.
   245     if (this->pbase() == _M_str.data()) {
   246       ptrdiff_t __avail = _M_str.data() + _M_str.size() - this->pptr();
   247       if (__avail > __n) {
   248         _Traits::assign(this->pptr(), __STATIC_CAST(size_t, __n), __c);
   249         this->pbump(__STATIC_CAST(int, __n));
   250         return __n;
   251       }
   252       else {
   253         _Traits::assign(this->pptr(), __avail, __c);
   254         __nwritten += __avail;
   255         __n -= __avail;
   256         this->setp(_M_Buf, _M_Buf + __STATIC_CAST(int,_S_BufSiz));
   257       }
   258     }
   259 
   260     // At this point we know we're appending.
   261     size_t __app_size = sizeof(streamsize) > sizeof(size_t) ? __STATIC_CAST(size_t, (min)(__n, __STATIC_CAST(streamsize, _M_str.max_size())))
   262                                                             : __STATIC_CAST(size_t, __n);
   263     if (this->_M_mode & ios_base::in) {
   264       ptrdiff_t __get_offset = this->gptr() - this->eback();
   265       _M_str.append(__app_size, __c);
   266 
   267       _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data());
   268       size_t __data_size = _M_str.size();
   269 
   270       this->setg(__data_ptr, __data_ptr + __get_offset, __data_ptr + __data_size);
   271       this->setp(__data_ptr, __data_ptr + __data_size);
   272       this->pbump((int)__data_size);
   273     }
   274     else {
   275       _M_append_buffer();
   276       _M_str.append(__app_size, __c);
   277     }
   278 
   279     __nwritten += __app_size;
   280   }
   281 
   282   return __nwritten;
   283 }
   284 
   285 // According to the C++ standard the effects of setbuf are implementation
   286 // defined, except that setbuf(0, 0) has no effect.  In this implementation,
   287 // setbuf(<anything>, n), for n > 0, calls reserve(n) on the underlying
   288 // string.
   289 template <class _CharT, class _Traits, class _Alloc>
   290 basic_streambuf<_CharT, _Traits>*
   291 basic_stringbuf<_CharT, _Traits, _Alloc>::setbuf(_CharT*, streamsize __n) {
   292   if (__n > 0) {
   293     bool __do_get_area = false;
   294     bool __do_put_area = false;
   295     ptrdiff_t __offg = 0;
   296     ptrdiff_t __offp = 0;
   297 
   298     if (this->pbase() == _M_str.data()) {
   299       __do_put_area = true;
   300       __offp = this->pptr() - this->pbase();
   301     }
   302 
   303     if (this->eback() == _M_str.data()) {
   304       __do_get_area = true;
   305       __offg = this->gptr() - this->eback();
   306     }
   307 
   308     if ((_M_mode & ios_base::out) && !(_M_mode & ios_base::in))
   309       _M_append_buffer();
   310 
   311     _M_str.reserve(sizeof(streamsize) > sizeof(size_t) ? __STATIC_CAST(size_t, (min)(__n, __STATIC_CAST(streamsize, _M_str.max_size())))
   312                                                        : __STATIC_CAST(size_t, __n));
   313 
   314     _CharT* __data_ptr = __CONST_CAST(_CharT*, _M_str.data());
   315     size_t __data_size = _M_str.size();
   316 
   317     if (__do_get_area) {
   318       this->setg(__data_ptr, __data_ptr + __offg, __data_ptr + __data_size);
   319     }
   320 
   321     if (__do_put_area) {
   322       this->setp(__data_ptr, __data_ptr + __data_size);
   323       this->pbump((int)__offp);
   324     }
   325   }
   326 
   327   return this;
   328 }
   329 
   330 template <class _CharT, class _Traits, class _Alloc>
   331 __BSB_pos_type__
   332 basic_stringbuf<_CharT, _Traits, _Alloc>
   333   ::seekoff(off_type __off,
   334             ios_base::seekdir __dir,
   335             ios_base::openmode __mode) {
   336   __mode &= _M_mode;
   337 
   338   bool __imode  = (__mode & ios_base::in) != 0;
   339   bool __omode = (__mode & ios_base::out) != 0;
   340 
   341   if ( !(__imode || __omode) )
   342     return pos_type(off_type(-1));
   343 
   344   if ( (__imode && (this->gptr() == 0)) || (__omode && (this->pptr() == 0)) )
   345     return pos_type(off_type(-1));
   346 
   347 #ifndef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
   348   if ((_M_mode & ios_base::out) && !(_M_mode & ios_base::in))
   349     _M_append_buffer();
   350 #endif
   351 
   352   streamoff __newoff;
   353   switch(__dir) {
   354   case ios_base::beg:
   355     __newoff = 0;
   356     break;
   357   case ios_base::end:
   358     __newoff = _M_str.size();
   359     break;
   360   case ios_base::cur:
   361     __newoff = __imode ? this->gptr() - this->eback() : this->pptr() - this->pbase();
   362 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
   363       if ( __off == 0 ) {
   364         return pos_type(__newoff);
   365       }
   366 #endif
   367     break;
   368   default:
   369     return pos_type(off_type(-1));
   370   }
   371 
   372   __off += __newoff;
   373 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
   374   _CharT* __data_ptr = __CONST_CAST(_CharT*, _M_str.data());
   375   size_t __data_size = _M_str.size();
   376 #endif
   377 
   378   if (__imode) {
   379     ptrdiff_t __n = this->egptr() - this->eback();
   380 
   381     if (__off < 0 || __off > __n)
   382       return pos_type(off_type(-1));
   383     this->setg(this->eback(), this->eback() + __STATIC_CAST(ptrdiff_t, __off),
   384                               this->eback() + __STATIC_CAST(ptrdiff_t, __n));
   385   }
   386 
   387   if (__omode) {
   388     ptrdiff_t __n = this->epptr() - this->pbase();
   389 
   390     if (__off < 0 || __off > __n)
   391       return pos_type(off_type(-1));
   392 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
   393  this->setp(__data_ptr, __data_ptr+__data_size);
   394 #else
   395     this->setp(this->pbase(), this->pbase() + __n);
   396 #endif
   397     this->pbump((int)__off);
   398   }
   399 
   400   return pos_type(__off);
   401 }
   402 
   403 template <class _CharT, class _Traits, class _Alloc>
   404 __BSB_pos_type__
   405 basic_stringbuf<_CharT, _Traits, _Alloc>
   406   ::seekpos(pos_type __pos, ios_base::openmode __mode) {
   407   __mode &= _M_mode;
   408 
   409   bool __imode  = (__mode & ios_base::in) != 0;
   410   bool __omode = (__mode & ios_base::out) != 0;
   411 
   412   if ( !(__imode || __omode) )
   413     return pos_type(off_type(-1));
   414 
   415   if ( (__imode && (this->gptr() == 0)) || (__omode && (this->pptr() == 0)) )
   416     return pos_type(off_type(-1));
   417 
   418   const off_type __n = __pos - pos_type(off_type(0));
   419   if ((_M_mode & ios_base::out) && !(_M_mode & ios_base::in))
   420     _M_append_buffer();
   421 
   422   if (__imode) {
   423     if (__n < 0 || __n > this->egptr() - this->eback())
   424       return pos_type(off_type(-1));
   425     this->setg(this->eback(), this->eback() + __STATIC_CAST(ptrdiff_t, __n), this->egptr());
   426   }
   427 
   428   if (__omode) {
   429     if (__n < 0 || size_t(__n) > _M_str.size())
   430       return pos_type(off_type(-1));
   431 
   432     _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data());
   433     size_t __data_size = _M_str.size();
   434 
   435     this->setp(__data_ptr, __data_ptr+__data_size);
   436     this->pbump((int)__n);
   437   }
   438 
   439   return __pos;
   440 }
   441 
   442 // This is declared as a const member function because it is
   443 // called by basic_stringbuf<>::str().  Precondition: this is a
   444 // write-only stringbuf.  We can't use an output buffer for read-
   445 // write stringbufs.  Postcondition: pptr is reset to the beginning
   446 // of the buffer.
   447 template <class _CharT, class _Traits, class _Alloc>
   448 void basic_stringbuf<_CharT, _Traits, _Alloc>::_M_append_buffer() const {
   449   // Do we have a buffer to append?
   450   if (this->pbase() == this->_M_Buf && this->pptr() != this->_M_Buf) {
   451     basic_stringbuf<_CharT, _Traits, _Alloc>* __this = __CONST_CAST(_Self*,this);
   452     __this->_M_str.append((const _CharT*)this->pbase(), (const _CharT*)this->pptr());
   453 #ifndef __MWERKS__
   454     __this->setp(__CONST_CAST(_CharT*,_M_Buf),
   455                  __CONST_CAST(_CharT*,_M_Buf + __STATIC_CAST(int,_S_BufSiz)));
   456 #else // CodeWarrior treat const char * and const char [8] as different types
   457     __this->setp((_CharT*)_M_Buf,
   458                  (_CharT*)(_M_Buf + __STATIC_CAST(int,_S_BufSiz)));
   459 #endif
   460   }
   461 
   462   // Have we run off the end of the string?
   463   else if (this->pptr() == this->epptr()) {
   464     basic_stringbuf<_CharT, _Traits, _Alloc>* __this = __CONST_CAST(_Self*,this);
   465 #ifndef __MWERKS__
   466     __this->setp(__CONST_CAST(_CharT*,_M_Buf),
   467                  __CONST_CAST(_CharT*,_M_Buf + __STATIC_CAST(int,_S_BufSiz)));
   468 #else // CodeWarrior treat const char * and const char [8] as different types
   469     __this->setp((_CharT*)_M_Buf,
   470                  (_CharT*)(_M_Buf + __STATIC_CAST(int,_S_BufSiz)));
   471 #endif
   472   }
   473 }
   474 
   475 //----------------------------------------------------------------------
   476 // Non-inline istringstream member functions.
   477 
   478 template <class _CharT, class _Traits, class _Alloc>
   479 basic_istringstream<_CharT, _Traits, _Alloc>
   480   ::basic_istringstream(ios_base::openmode __mode)
   481     : basic_istream<_CharT, _Traits>(0),
   482       _M_buf(__mode | ios_base::in) {
   483   this->init(&_M_buf);
   484 }
   485 
   486 template <class _CharT, class _Traits, class _Alloc>
   487 basic_istringstream<_CharT, _Traits, _Alloc>
   488   ::basic_istringstream(const _String& __str,ios_base::openmode __mode)
   489     : basic_istream<_CharT, _Traits>(0),
   490       _M_buf(__str, __mode | ios_base::in) {
   491   this->init(&_M_buf);
   492 }
   493 
   494 template <class _CharT, class _Traits, class _Alloc>
   495 basic_istringstream<_CharT, _Traits, _Alloc>::~basic_istringstream()
   496 {}
   497 
   498 //----------------------------------------------------------------------
   499 // Non-inline ostringstream member functions.
   500 
   501 template <class _CharT, class _Traits, class _Alloc>
   502 basic_ostringstream<_CharT, _Traits, _Alloc>
   503   ::basic_ostringstream(ios_base::openmode __mode)
   504     : basic_ostream<_CharT, _Traits>(0),
   505       _M_buf(__mode | ios_base::out) {
   506   this->init(&_M_buf);
   507 }
   508 
   509 template <class _CharT, class _Traits, class _Alloc>
   510 basic_ostringstream<_CharT, _Traits, _Alloc>
   511   ::basic_ostringstream(const _String& __str, ios_base::openmode __mode)
   512     : basic_ostream<_CharT, _Traits>(0),
   513       _M_buf(__str, __mode | ios_base::out) {
   514   this->init(&_M_buf);
   515 }
   516 
   517 template <class _CharT, class _Traits, class _Alloc>
   518 basic_ostringstream<_CharT, _Traits, _Alloc>::~basic_ostringstream()
   519 {}
   520 
   521 //----------------------------------------------------------------------
   522 // Non-inline stringstream member functions.
   523 
   524 template <class _CharT, class _Traits, class _Alloc>
   525 basic_stringstream<_CharT, _Traits, _Alloc>
   526   ::basic_stringstream(ios_base::openmode __mode)
   527     : basic_iostream<_CharT, _Traits>(0), _M_buf(__mode) {
   528    this->init(&_M_buf);
   529 }
   530 
   531 template <class _CharT, class _Traits, class _Alloc>
   532 basic_stringstream<_CharT, _Traits, _Alloc>
   533   ::basic_stringstream(const _String& __str, ios_base::openmode __mode)
   534     : basic_iostream<_CharT, _Traits>(0), _M_buf(__str, __mode) {
   535   this->init(&_M_buf);
   536 }
   537 
   538 template <class _CharT, class _Traits, class _Alloc>
   539 basic_stringstream<_CharT, _Traits, _Alloc>::~basic_stringstream()
   540 {}
   541 
   542 _STLP_END_NAMESPACE
   543 
   544 # undef __BSB_int_type__
   545 # undef __BSB_pos_type__
   546 
   547 #endif /* _STLP_SSTREAM_C */
   548 
   549 // Local Variables:
   550 // mode:C++
   551 // End: