genericopenlibs/cppstdlib/stl/src/strstream.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 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 
       
    29 #include <strstream>
       
    30 #include <algorithm>
       
    31 #include <limits>
       
    32 
       
    33 _STLP_BEGIN_NAMESPACE
       
    34 
       
    35 // strstreambuf constructor, destructor.
       
    36 _STLP_DECLSPEC strstreambuf::strstreambuf(streamsize initial_capacity)
       
    37    : _M_alloc_fun(0), _M_free_fun(0),
       
    38      _M_dynamic(true), _M_frozen(false), _M_constant(false) {
       
    39   size_t n = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()),
       
    40                                                                                  (max)(initial_capacity, streamsize(16))))
       
    41                                                    : __STATIC_CAST(size_t, (max)(initial_capacity, streamsize(16)));
       
    42 
       
    43   char* buf = _M_alloc(n);
       
    44   if (buf) {
       
    45     setp(buf, buf + n);
       
    46     setg(buf, buf, buf);
       
    47   }
       
    48 }
       
    49 
       
    50 _STLP_DECLSPEC strstreambuf::strstreambuf(__alloc_fn alloc_f, __free_fn free_f)
       
    51   : _M_alloc_fun(alloc_f), _M_free_fun(free_f),
       
    52     _M_dynamic(true), _M_frozen(false), _M_constant(false) {
       
    53   size_t n = 16;
       
    54 
       
    55   char* buf = _M_alloc(n);
       
    56   if (buf) {
       
    57     setp(buf, buf + n);
       
    58     setg(buf, buf, buf);
       
    59   }
       
    60 }
       
    61 
       
    62 _STLP_DECLSPEC strstreambuf::strstreambuf(char* get, streamsize n, char* put)
       
    63   : _M_alloc_fun(0), _M_free_fun(0),
       
    64     _M_dynamic(false), _M_frozen(false), _M_constant(false) {
       
    65   _M_setup(get, put, n);
       
    66 }
       
    67 
       
    68 _STLP_DECLSPEC strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
       
    69   : _M_alloc_fun(0), _M_free_fun(0),
       
    70     _M_dynamic(false), _M_frozen(false), _M_constant(false) {
       
    71   _M_setup(__REINTERPRET_CAST(char*,get), __REINTERPRET_CAST(char*,put), n);
       
    72 }
       
    73 
       
    74 _STLP_DECLSPEC strstreambuf::strstreambuf(unsigned char* get, streamsize n,
       
    75                            unsigned char* put)
       
    76   : _M_alloc_fun(0), _M_free_fun(0),
       
    77     _M_dynamic(false), _M_frozen(false), _M_constant(false) {
       
    78   _M_setup(__REINTERPRET_CAST(char*,get), __REINTERPRET_CAST(char*,put), n);
       
    79 }
       
    80 
       
    81 _STLP_DECLSPEC strstreambuf::strstreambuf(const char* get, streamsize n)
       
    82   : _M_alloc_fun(0), _M_free_fun(0),
       
    83     _M_dynamic(false), _M_frozen(false), _M_constant(true) {
       
    84   _M_setup(__CONST_CAST(char*,get), 0, n);
       
    85 }
       
    86 
       
    87 _STLP_DECLSPEC strstreambuf::strstreambuf(const signed char* get, streamsize n)
       
    88   : _M_alloc_fun(0), _M_free_fun(0),
       
    89     _M_dynamic(false), _M_frozen(false), _M_constant(true) {
       
    90   _M_setup(__REINTERPRET_CAST(char*, __CONST_CAST(signed char*,get)), 0, n);
       
    91 }
       
    92 
       
    93 _STLP_DECLSPEC strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
       
    94   : _M_alloc_fun(0), _M_free_fun(0),
       
    95     _M_dynamic(false), _M_frozen(false), _M_constant(true) {
       
    96   _M_setup(__REINTERPRET_CAST(char*, __CONST_CAST(unsigned char*,get)), 0, n);
       
    97 }
       
    98 
       
    99 _STLP_DECLSPEC strstreambuf::~strstreambuf() {
       
   100   if (_M_dynamic && !_M_frozen)
       
   101     _M_free(eback());
       
   102 }
       
   103 
       
   104 _STLP_DECLSPEC void strstreambuf::freeze(bool frozenflag) {
       
   105   if (_M_dynamic)
       
   106     _M_frozen = frozenflag;
       
   107 }
       
   108 
       
   109 _STLP_DECLSPEC char* strstreambuf::str() {
       
   110   freeze(true);
       
   111   return eback();
       
   112 }
       
   113 
       
   114 _STLP_DECLSPEC int strstreambuf::pcount() const {
       
   115   return int(pptr() ? pptr() - pbase() : 0);
       
   116 }
       
   117 
       
   118 _STLP_DECLSPEC strstreambuf::int_type strstreambuf::overflow(int_type c) {
       
   119   if (c == traits_type::eof())
       
   120     return traits_type::not_eof(c);
       
   121 
       
   122   // Try to expand the buffer.
       
   123   if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) {
       
   124     ptrdiff_t old_size = epptr() - pbase();
       
   125     ptrdiff_t new_size = (max)(2 * old_size, ptrdiff_t(1));
       
   126 
       
   127     char* buf = _M_alloc(new_size);
       
   128     if (buf) {
       
   129       memcpy(buf, pbase(), old_size);
       
   130 
       
   131       char* old_buffer = pbase();
       
   132       bool reposition_get = false;
       
   133       ptrdiff_t old_get_offset;
       
   134       if (gptr() != 0) {
       
   135         reposition_get = true;
       
   136         old_get_offset = gptr() - eback();
       
   137       }
       
   138 
       
   139       setp(buf, buf + new_size);
       
   140       pbump((int)old_size);
       
   141 
       
   142       if (reposition_get)
       
   143         setg(buf, buf + old_get_offset, buf + (max)(old_get_offset, old_size));
       
   144 
       
   145       _M_free(old_buffer);
       
   146     }
       
   147   }
       
   148 
       
   149   if (pptr() != epptr()) {
       
   150     *pptr() = traits_type::to_char_type(c);
       
   151     pbump(1);
       
   152     return c;
       
   153   }
       
   154   else
       
   155     return traits_type::eof();
       
   156 }
       
   157 
       
   158 _STLP_DECLSPEC strstreambuf::int_type strstreambuf::pbackfail(int_type c) {
       
   159   if (gptr() != eback()) {
       
   160     if (c == traits_type::eof()) {
       
   161       gbump(-1);
       
   162       return traits_type::not_eof(c);
       
   163     }
       
   164     else if (c == gptr()[-1]) {
       
   165       gbump(-1);
       
   166       return c;
       
   167     }
       
   168     else if (!_M_constant) {
       
   169       gbump(-1);
       
   170       *gptr() = traits_type::to_char_type(c);
       
   171       return c;
       
   172     }
       
   173   }
       
   174 
       
   175   return traits_type::eof();
       
   176 }
       
   177 
       
   178 _STLP_DECLSPEC strstreambuf::int_type strstreambuf::underflow() {
       
   179   if (gptr() == egptr() && pptr() && pptr() > egptr())
       
   180     setg(eback(), gptr(), pptr());
       
   181 
       
   182   if (gptr() != egptr())
       
   183     return (unsigned char) *gptr();
       
   184   else
       
   185     return _Traits::eof();
       
   186 }
       
   187 
       
   188 _STLP_DECLSPEC basic_streambuf<char, char_traits<char> >*
       
   189 strstreambuf::setbuf(char*, streamsize) {
       
   190   return this;
       
   191 }
       
   192 
       
   193 _STLP_DECLSPEC strstreambuf::pos_type
       
   194 strstreambuf::seekoff(off_type off,
       
   195                       ios_base::seekdir dir, ios_base::openmode mode) {
       
   196   bool do_get = false;
       
   197   bool do_put = false;
       
   198 
       
   199   if ((mode & (ios_base::in | ios_base::out)) ==
       
   200           (ios_base::in | ios_base::out) &&
       
   201       (dir == ios_base::beg || dir == ios_base::end))
       
   202     do_get = do_put = true;
       
   203   else if (mode & ios_base::in)
       
   204     do_get = true;
       
   205   else if (mode & ios_base::out)
       
   206     do_put = true;
       
   207 
       
   208   // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
       
   209   // area is undefined if there is no get area.
       
   210   if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
       
   211     return pos_type(off_type(-1));
       
   212 
       
   213   char* seeklow  = eback();
       
   214   char* seekhigh = epptr() ? epptr() : egptr();
       
   215 
       
   216   off_type newoff;
       
   217   switch(dir) {
       
   218   case ios_base::beg:
       
   219     newoff = 0;
       
   220     break;
       
   221   case ios_base::end:
       
   222     newoff = seekhigh - seeklow;
       
   223     break;
       
   224   case ios_base::cur:
       
   225     newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
       
   226     break;
       
   227   default:
       
   228     return pos_type(off_type(-1));
       
   229   }
       
   230 
       
   231   off += newoff;
       
   232   if (off < 0 || off > seekhigh - seeklow)
       
   233     return pos_type(off_type(-1));
       
   234 
       
   235   if (do_put) {
       
   236     if (seeklow + __STATIC_CAST(ptrdiff_t, off) < pbase()) {
       
   237       setp(seeklow, epptr());
       
   238       pbump((int)off);
       
   239     }
       
   240     else {
       
   241       setp(pbase(), epptr());
       
   242       pbump((int)(off - (pbase() - seeklow)));
       
   243     }
       
   244   }
       
   245   if (do_get) {
       
   246     if (off <= egptr() - seeklow)
       
   247       setg(seeklow, seeklow + __STATIC_CAST(ptrdiff_t, off), egptr());
       
   248     else if (off <= pptr() - seeklow)
       
   249       setg(seeklow, seeklow + __STATIC_CAST(ptrdiff_t, off), pptr());
       
   250     else
       
   251       setg(seeklow, seeklow + __STATIC_CAST(ptrdiff_t, off), epptr());
       
   252   }
       
   253 
       
   254   return pos_type(newoff);
       
   255 }
       
   256 
       
   257 _STLP_DECLSPEC strstreambuf::pos_type
       
   258 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode) {
       
   259   return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
       
   260 }
       
   261 
       
   262 
       
   263 char* strstreambuf::_M_alloc(size_t n) {
       
   264   if (_M_alloc_fun)
       
   265     return __STATIC_CAST(char*,_M_alloc_fun(n));
       
   266   else
       
   267     return new char[n];
       
   268 }
       
   269 
       
   270 void strstreambuf::_M_free(char* p) {
       
   271   if (p)
       
   272     if (_M_free_fun)
       
   273       _M_free_fun(p);
       
   274     else
       
   275       delete[] p;
       
   276 }
       
   277 
       
   278 void strstreambuf::_M_setup(char* get, char* put, streamsize n) {
       
   279   if (get) {
       
   280     size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
       
   281 
       
   282     if (put) {
       
   283       setg(get, get, get + N);
       
   284       setp(put, put + N);
       
   285     }
       
   286     else {
       
   287       setg(get, get, get + N);
       
   288     }
       
   289   }
       
   290 }
       
   291 
       
   292 //----------------------------------------------------------------------
       
   293 // Class istrstream
       
   294 
       
   295 _STLP_DECLSPEC istrstream::istrstream(char* s)
       
   296   : basic_istream<char, char_traits<char> >(0), _M_buf(s, 0) {
       
   297   this->init(&_M_buf);
       
   298 }
       
   299 
       
   300 _STLP_DECLSPEC istrstream::istrstream(const char* s)
       
   301   : basic_istream<char, char_traits<char> >(0), _M_buf(s, 0) {
       
   302   this->init(&_M_buf);
       
   303 }
       
   304 
       
   305 _STLP_DECLSPEC istrstream::istrstream(char* s, streamsize n)
       
   306   : basic_istream<char, char_traits<char> >(0), _M_buf(s, n) {
       
   307   this->init(&_M_buf);
       
   308 }
       
   309 
       
   310 _STLP_DECLSPEC istrstream::istrstream(const char* s, streamsize n)
       
   311   : basic_istream<char, char_traits<char> >(0), _M_buf(s, n) {
       
   312   this->init(&_M_buf);
       
   313 }
       
   314 
       
   315 _STLP_DECLSPEC istrstream::~istrstream() {}
       
   316 
       
   317 _STLP_DECLSPEC strstreambuf* istrstream::rdbuf() const {
       
   318   return __CONST_CAST(strstreambuf*,&_M_buf);
       
   319 }
       
   320 
       
   321 _STLP_DECLSPEC char* istrstream::str() { return _M_buf.str(); }
       
   322 
       
   323 //----------------------------------------------------------------------
       
   324 // Class ostrstream
       
   325 
       
   326 _STLP_DECLSPEC ostrstream::ostrstream()
       
   327   : basic_ostream<char, char_traits<char> >(0), _M_buf() {
       
   328   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   329 }
       
   330 
       
   331 _STLP_DECLSPEC ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
       
   332   : basic_ostream<char, char_traits<char> >(0),
       
   333     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s) {
       
   334   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   335 }
       
   336 
       
   337 _STLP_DECLSPEC ostrstream::~ostrstream() {}
       
   338 
       
   339 _STLP_DECLSPEC strstreambuf* ostrstream::rdbuf() const {
       
   340   return __CONST_CAST(strstreambuf*,&_M_buf);
       
   341 }
       
   342 
       
   343 _STLP_DECLSPEC void ostrstream::freeze(bool freezeflag) {
       
   344   _M_buf.freeze(freezeflag);
       
   345 }
       
   346 
       
   347 _STLP_DECLSPEC char* ostrstream::str() {
       
   348   return _M_buf.str();
       
   349 }
       
   350 
       
   351 _STLP_DECLSPEC int ostrstream::pcount() const {
       
   352   return _M_buf.pcount();
       
   353 }
       
   354 
       
   355 
       
   356 //----------------------------------------------------------------------
       
   357 // Class strstream
       
   358 
       
   359 _STLP_DECLSPEC strstream::strstream()
       
   360   : basic_iostream<char, char_traits<char> >(0), _M_buf() {
       
   361   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   362 }
       
   363 
       
   364 _STLP_DECLSPEC strstream::strstream(char* s, int n, ios_base::openmode mode)
       
   365   : basic_iostream<char, char_traits<char> >(0),
       
   366     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s) {
       
   367   basic_ios<char, char_traits<char> >::init(&_M_buf);
       
   368 }
       
   369 
       
   370 _STLP_DECLSPEC strstream::~strstream() {}
       
   371 
       
   372 _STLP_DECLSPEC strstreambuf* strstream::rdbuf() const {
       
   373   return __CONST_CAST(strstreambuf*,&_M_buf);
       
   374 }
       
   375 
       
   376 _STLP_DECLSPEC void strstream::freeze(bool freezeflag) {
       
   377   _M_buf.freeze(freezeflag);
       
   378 }
       
   379 
       
   380 _STLP_DECLSPEC int strstream::pcount() const {
       
   381   return _M_buf.pcount();
       
   382 }
       
   383 
       
   384 _STLP_DECLSPEC char* strstream::str() {
       
   385   return _M_buf.str();
       
   386 }
       
   387 
       
   388 _STLP_END_NAMESPACE
       
   389 
       
   390 // Local Variables:
       
   391 // mode:C++
       
   392 // End: