stdcpp/src/strstream.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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 
       
    21 // Implementation of the classes in header <strstream>.
       
    22 // WARNING: The classes defined in <strstream> are DEPRECATED.  This
       
    23 // header is defined in section D.7.1 of the C++ standard, and it
       
    24 // MAY BE REMOVED in a future standard revision.  You should use the
       
    25 // header <sstream> instead.
       
    26 
       
    27 # include "stlport_prefix.h"
       
    28 #include <stl/_strstream.h>
       
    29 #include <stl/_algobase.h>
       
    30 
       
    31 _STLP_BEGIN_NAMESPACE
       
    32 
       
    33 // strstreambuf constructor, destructor.
       
    34 
       
    35 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(streamsize initial_capacity)
       
    36    :  _M_alloc_fun(0), _M_free_fun(0),
       
    37      _M_dynamic(true), _M_frozen(false), _M_constant(false)  
       
    38 #ifdef __SYMBIAN32__
       
    39     , _pfrozenendsave(NULL)
       
    40     ,_pgetfrozenendsave( NULL)
       
    41 #endif     
       
    42 {
       
    43   streamsize n = (max)(initial_capacity, streamsize(16));
       
    44 
       
    45   char* buf = _M_alloc(n);
       
    46 #ifdef __SYMBIAN32__  
       
    47   *buf = '\0';
       
    48 #endif  
       
    49   if (buf) {
       
    50     setp(buf, buf + n);
       
    51     setg(buf, buf, buf);
       
    52   }
       
    53 }
       
    54 
       
    55 
       
    56 
       
    57 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(__alloc_fn alloc_f, __free_fn free_f)
       
    58   : _M_alloc_fun(alloc_f), _M_free_fun(free_f),
       
    59     _M_dynamic(true), _M_frozen(false), _M_constant(false)
       
    60 #ifdef __SYMBIAN32__
       
    61     , _pfrozenendsave(NULL)
       
    62     ,_pgetfrozenendsave( NULL)
       
    63 #endif     
       
    64 {
       
    65   streamsize n = 16;
       
    66 #ifndef __SYMBIAN32__  
       
    67   char* buf = _M_alloc(n);
       
    68 #else
       
    69   char* buf = NULL;
       
    70   if(alloc_f!=NULL)
       
    71   	buf = (char*)_M_alloc_fun(n);
       
    72   else
       
    73   	buf = _M_alloc(n);
       
    74   if(buf)
       
    75   	*buf = '\0';
       
    76 #endif 
       
    77   if (buf) {
       
    78     setp(buf, buf + n);
       
    79     setg(buf, buf, buf);
       
    80   }
       
    81 }
       
    82 
       
    83 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(char* get, streamsize n, char* put)
       
    84   : _M_alloc_fun(0), _M_free_fun(0),
       
    85     _M_dynamic(false), _M_frozen(false), _M_constant(false)
       
    86 #ifdef __SYMBIAN32__
       
    87     , _pfrozenendsave(NULL)
       
    88     ,_pgetfrozenendsave( NULL)
       
    89 #endif     
       
    90 {
       
    91   _M_setup(get, put, n);
       
    92 }
       
    93 
       
    94 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
       
    95   : _M_alloc_fun(0), _M_free_fun(0),
       
    96     _M_dynamic(false), _M_frozen(false), _M_constant(false)
       
    97 #ifdef __SYMBIAN32__
       
    98     , _pfrozenendsave(NULL)
       
    99     ,_pgetfrozenendsave( NULL)
       
   100 #endif     
       
   101 {
       
   102   _M_setup(__REINTERPRET_CAST(char*,get), __REINTERPRET_CAST(char*,put), n);
       
   103 }
       
   104 
       
   105 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(unsigned char* get, streamsize n,
       
   106                            unsigned char* put)
       
   107   : _M_alloc_fun(0), _M_free_fun(0),
       
   108     _M_dynamic(false), _M_frozen(false), _M_constant(false)
       
   109 #ifdef __SYMBIAN32__
       
   110     , _pfrozenendsave(NULL)
       
   111     ,_pgetfrozenendsave( NULL)
       
   112 #endif     
       
   113 {
       
   114   _M_setup(__REINTERPRET_CAST(char*,get), __REINTERPRET_CAST(char*,put), n);
       
   115 }
       
   116 
       
   117 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(const char* get, streamsize n)
       
   118   : _M_alloc_fun(0), _M_free_fun(0),
       
   119     _M_dynamic(false), _M_frozen(false), _M_constant(true)
       
   120 #ifdef __SYMBIAN32__
       
   121     , _pfrozenendsave(NULL)
       
   122     ,_pgetfrozenendsave( NULL)
       
   123 #endif     
       
   124 {
       
   125   _M_setup(__CONST_CAST(char*,get), 0, n);
       
   126 }
       
   127 
       
   128 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(const signed char* get, streamsize n)
       
   129   : _M_alloc_fun(0), _M_free_fun(0),
       
   130     _M_dynamic(false), _M_frozen(false), _M_constant(true)
       
   131 #ifdef __SYMBIAN32__
       
   132     , _pfrozenendsave(NULL)
       
   133     ,_pgetfrozenendsave( NULL)
       
   134 #endif     
       
   135 {
       
   136   _M_setup(__REINTERPRET_CAST(char*, __CONST_CAST(signed char*,get)), 0, n);
       
   137 }
       
   138 
       
   139 _STLP_EXP_DECLSPEC strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
       
   140   : _M_alloc_fun(0), _M_free_fun(0),
       
   141     _M_dynamic(false), _M_frozen(false), _M_constant(true)
       
   142 #ifdef __SYMBIAN32__
       
   143     , _pfrozenendsave(NULL)
       
   144     ,_pgetfrozenendsave( NULL)
       
   145 #endif     
       
   146 {
       
   147   _M_setup(__REINTERPRET_CAST(char*, __CONST_CAST(unsigned char*,get)), 0, n);
       
   148 }
       
   149 
       
   150 _STLP_EXP_DECLSPEC void strstreambuf::freeze(bool frozenflag)
       
   151 {
       
   152 #ifdef __SYMBIAN32__
       
   153   if (_M_dynamic)
       
   154   {
       
   155     //
       
   156 	if (frozenflag && !_M_frozen)
       
   157 		{	// disable writing
       
   158 		_M_frozen = frozenflag;
       
   159 		_pfrozenendsave = epptr();
       
   160         _pgetfrozenendsave = pptr();
       
   161 		setp(pbase(), eback());
       
   162 		}
       
   163 	else if (!frozenflag && _M_frozen)
       
   164 		{	// re-enable writing
       
   165 		_M_frozen = frozenflag;
       
   166 		if(_pfrozenendsave != NULL)
       
   167 		    {
       
   168 		    setp(pbase(), _pfrozenendsave);
       
   169 		    setg(pbase(),  pbase(), _pgetfrozenendsave);
       
   170 		    }
       
   171 		}
       
   172   }
       
   173 #else
       
   174   if (_M_dynamic)
       
   175     _M_frozen = frozenflag;
       
   176 #endif
       
   177 }
       
   178 
       
   179 _STLP_EXP_DECLSPEC char* strstreambuf::str()
       
   180 {
       
   181   freeze(true);
       
   182   return eback();
       
   183 }
       
   184 
       
   185 _STLP_EXP_DECLSPEC int strstreambuf::pcount() const
       
   186 {
       
   187   return int(pptr() ? pptr() - pbase() : 0);
       
   188 }
       
   189 
       
   190 _STLP_EXP_DECLSPEC strstreambuf::int_type strstreambuf::overflow(int_type c) {
       
   191   if (c == traits_type::eof())
       
   192     return traits_type::not_eof(c);
       
   193 #ifdef __SYMBIAN32__
       
   194   if (pptr() != 0 && pptr() < epptr())
       
   195   {
       
   196     *pptr() = c;
       
   197     pbump(1);
       
   198     return c;
       
   199   }
       
   200   if (!_M_dynamic || _M_constant || _M_frozen)
       
   201   	return (EOF);	// can't extend
       
   202 #endif
       
   203   // Try to expand the buffer.
       
   204   if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) {
       
   205     ptrdiff_t old_size = epptr() - pbase();
       
   206     ptrdiff_t new_size = (max)(2 * old_size, ptrdiff_t(1));
       
   207 
       
   208     char* buf = _M_alloc(new_size);
       
   209     if (buf) {
       
   210       memcpy(buf, pbase(), old_size);
       
   211 
       
   212       char* old_buffer = pbase();
       
   213       bool reposition_get = false;
       
   214       ptrdiff_t old_get_offset;
       
   215       if (gptr() != 0) {
       
   216         reposition_get = true;
       
   217         old_get_offset = gptr() - eback();
       
   218       }
       
   219 
       
   220       setp(buf, buf + new_size);
       
   221       pbump((int)old_size);
       
   222 
       
   223       if (reposition_get) 
       
   224         setg(buf, buf + old_get_offset, buf + (max)(old_get_offset, old_size));
       
   225 
       
   226       _M_free(old_buffer);
       
   227     }
       
   228   }
       
   229 
       
   230   if (pptr() != epptr()) {
       
   231     *pptr() = c;
       
   232     pbump(1);
       
   233     return c;
       
   234   }
       
   235   else
       
   236     return traits_type::eof();
       
   237 }
       
   238 
       
   239 _STLP_EXP_DECLSPEC strstreambuf::int_type strstreambuf::pbackfail(int_type c)
       
   240 {
       
   241   if (gptr() != eback()) {
       
   242     if (c == _Traits::eof()) {
       
   243       gbump(-1);
       
   244       return _Traits::not_eof(c);
       
   245     }
       
   246     else if (c == gptr()[-1]) {
       
   247       gbump(-1);
       
   248       return c;
       
   249     }
       
   250     else if (!_M_constant) {
       
   251       gbump(-1);
       
   252       *gptr() = c;
       
   253       return c;
       
   254     }
       
   255   }
       
   256 
       
   257   return _Traits::eof();
       
   258 }
       
   259 
       
   260 _STLP_EXP_DECLSPEC strstreambuf::int_type strstreambuf::underflow()
       
   261 {
       
   262   if (gptr() == egptr() && pptr() && pptr() > egptr())
       
   263     setg(eback(), gptr(), pptr());
       
   264 
       
   265   if (gptr() != egptr())
       
   266     return (unsigned char) *gptr();
       
   267   else
       
   268     return _Traits::eof();
       
   269 }
       
   270 
       
   271 _STLP_EXP_DECLSPEC basic_streambuf<char, char_traits<char> >* 
       
   272 strstreambuf::setbuf(char*, streamsize)
       
   273 {
       
   274   return this;
       
   275 }
       
   276 
       
   277 _STLP_EXP_DECLSPEC strstreambuf::pos_type
       
   278 strstreambuf::seekoff(off_type off,
       
   279                       ios_base::seekdir dir, ios_base::openmode mode)
       
   280 {
       
   281   bool do_get = false;
       
   282   bool do_put = false;
       
   283 
       
   284   if ((mode & (ios_base::in | ios_base::out)) ==
       
   285           (ios_base::in | ios_base::out) &&
       
   286       (dir == ios_base::beg || dir == ios_base::end))
       
   287     do_get = do_put = true;
       
   288   else if (mode & ios_base::in)
       
   289     do_get = true;
       
   290   else if (mode & ios_base::out)
       
   291     do_put = true;
       
   292 
       
   293   // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
       
   294   // area is undefined if there is no get area.
       
   295   if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
       
   296     return pos_type(off_type(-1));
       
   297 
       
   298   char* seeklow  = eback();
       
   299   char* seekhigh = epptr() ? epptr() : egptr();
       
   300 
       
   301   off_type newoff;
       
   302   switch(dir) {
       
   303   case ios_base::beg:
       
   304     newoff = 0;
       
   305     break;
       
   306   case ios_base::end:
       
   307     newoff = seekhigh - seeklow;
       
   308     break;
       
   309   case ios_base::cur:
       
   310     newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
       
   311     break;
       
   312   default:
       
   313     return pos_type(off_type(-1));
       
   314   }
       
   315 
       
   316   off += newoff;
       
   317   if (off < 0 || off > seekhigh - seeklow)
       
   318     return pos_type(off_type(-1));
       
   319 
       
   320   if (do_put) {
       
   321     if (seeklow + off < pbase()) {
       
   322       setp(seeklow, epptr());
       
   323       pbump((int)off);
       
   324     }
       
   325     else {
       
   326       setp(pbase(), epptr());
       
   327       pbump((int)(off - (pbase() - seeklow)));
       
   328     }
       
   329   }
       
   330   if (do_get) {
       
   331     if (off <= egptr() - seeklow)
       
   332       setg(seeklow, seeklow + off, egptr());
       
   333     else if (off <= pptr() - seeklow)
       
   334       setg(seeklow, seeklow + off, pptr());
       
   335     else
       
   336       setg(seeklow, seeklow + off, epptr());
       
   337   }
       
   338 #ifndef __SYMBIAN32__
       
   339   return pos_type(newoff);
       
   340 #else
       
   341   return pos_type(off);
       
   342 #endif  
       
   343 }
       
   344 
       
   345 _STLP_EXP_DECLSPEC strstreambuf::pos_type
       
   346 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
       
   347 {
       
   348   return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
       
   349 }
       
   350 
       
   351 
       
   352 char* strstreambuf::_M_alloc(size_t n)
       
   353 {
       
   354   if (_M_alloc_fun)
       
   355     return __STATIC_CAST(char*,_M_alloc_fun(n));
       
   356   else
       
   357     return new char[n];
       
   358 }
       
   359 
       
   360 void strstreambuf::_M_setup(char* get, char* put, streamsize n)
       
   361 {
       
   362   if (get) {
       
   363     size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
       
   364     
       
   365     if (put) {
       
   366       if(put == get)
       
   367         setg(get, get, put + N);
       
   368       else
       
   369 #ifndef __SYMBIAN32__      
       
   370       	setg(get, get, put);      
       
   371       	setp(put, put + N);
       
   372 #else
       
   373 		setg(get, get, put + N-(put-get));      
       
   374 		setp(put, put + N-(put-get));
       
   375 #endif      	
       
   376     }
       
   377     else {
       
   378       setg(get, get, get + N);
       
   379     }
       
   380   }
       
   381 }
       
   382 
       
   383 //----------------------------------------------------------------------
       
   384 // Class istrstream
       
   385 
       
   386 _STLP_EXP_DECLSPEC istrstream::istrstream(char* s)
       
   387   : basic_istream<char, char_traits<char> >(0), _M_buf(s, 0)
       
   388 {
       
   389   this->init(&_M_buf);
       
   390 }
       
   391 
       
   392 _STLP_EXP_DECLSPEC istrstream::istrstream(const char* s)
       
   393   : basic_istream<char, char_traits<char> >(0), _M_buf(s, 0)
       
   394 {
       
   395   this->init(&_M_buf);
       
   396 }
       
   397 
       
   398 _STLP_EXP_DECLSPEC istrstream::istrstream(char* s, streamsize n)
       
   399   : basic_istream<char, char_traits<char> >(0), _M_buf(s, n)
       
   400 {
       
   401   this->init(&_M_buf);
       
   402 }
       
   403 
       
   404 _STLP_EXP_DECLSPEC istrstream::istrstream(const char* s, streamsize n)
       
   405   : basic_istream<char, char_traits<char> >(0), _M_buf(s, n)
       
   406 {
       
   407   this->init(&_M_buf);
       
   408 }
       
   409 
       
   410 _STLP_EXP_DECLSPEC istrstream::~istrstream() {}
       
   411 
       
   412 _STLP_EXP_DECLSPEC strstreambuf* istrstream::rdbuf() const {
       
   413   return __CONST_CAST(strstreambuf*,&_M_buf);
       
   414 }
       
   415 
       
   416 _STLP_EXP_DECLSPEC char* istrstream::str() { return _M_buf.str(); }
       
   417 
       
   418 //----------------------------------------------------------------------
       
   419 // Class ostrstream
       
   420 
       
   421 _STLP_EXP_DECLSPEC ostrstream::ostrstream()
       
   422   : basic_ostream<char, char_traits<char> >(0), _M_buf()
       
   423 {
       
   424   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   425 }
       
   426 
       
   427 _STLP_EXP_DECLSPEC ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
       
   428   : basic_ostream<char, char_traits<char> >(0), 
       
   429     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
       
   430 {
       
   431   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   432 }
       
   433 
       
   434 _STLP_EXP_DECLSPEC ostrstream::~ostrstream() {}
       
   435 
       
   436 _STLP_EXP_DECLSPEC strstreambuf* ostrstream::rdbuf() const 
       
   437 {
       
   438   return __CONST_CAST(strstreambuf*,&_M_buf);
       
   439 }
       
   440 
       
   441 _STLP_EXP_DECLSPEC void ostrstream::freeze(bool freezeflag)
       
   442 {
       
   443   _M_buf.freeze(freezeflag);
       
   444 }
       
   445 
       
   446 _STLP_EXP_DECLSPEC char* ostrstream::str()
       
   447 {
       
   448   return _M_buf.str();
       
   449 }
       
   450 
       
   451 _STLP_EXP_DECLSPEC int ostrstream::pcount() const
       
   452 {
       
   453   return _M_buf.pcount();
       
   454 }
       
   455 
       
   456 
       
   457 //----------------------------------------------------------------------
       
   458 // Class strstream
       
   459 
       
   460 _STLP_EXP_DECLSPEC strstream::strstream()
       
   461   : basic_iostream<char, char_traits<char> >(0), _M_buf()
       
   462 {
       
   463   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   464 }
       
   465 
       
   466 _STLP_EXP_DECLSPEC strstream::strstream(char* s, int n, ios_base::openmode mode)
       
   467   : basic_iostream<char, char_traits<char> >(0), 
       
   468     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
       
   469 {
       
   470   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   471 }
       
   472   
       
   473 _STLP_EXP_DECLSPEC strstream::~strstream() {}
       
   474 
       
   475 _STLP_EXP_DECLSPEC strstreambuf* strstream::rdbuf() const
       
   476 {
       
   477   return __CONST_CAST(strstreambuf*,&_M_buf);
       
   478 }
       
   479 
       
   480 _STLP_EXP_DECLSPEC void strstream::freeze(bool freezeflag)
       
   481 {
       
   482   _M_buf.freeze(freezeflag);
       
   483 }
       
   484 
       
   485 _STLP_EXP_DECLSPEC int strstream::pcount() const
       
   486 {
       
   487   return _M_buf.pcount();
       
   488 }
       
   489 
       
   490 _STLP_EXP_DECLSPEC char* strstream::str()
       
   491 {
       
   492   return _M_buf.str();
       
   493 }
       
   494 
       
   495 _STLP_END_NAMESPACE
       
   496 
       
   497 // Local Variables:
       
   498 // mode:C++
       
   499 // End: