os/ossrv/genericopenlibs/cppstdlib/stl/src/strstream.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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: