Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

strstream.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1998
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Permission to use, copy, modify, distribute and sell this software
00006  * and its documentation for any purpose is hereby granted without fee,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation.  Silicon Graphics makes no
00010  * representations about the suitability of this software for any
00011  * purpose.  It is provided "as is" without express or implied warranty.
00012  */
00013 
00014 // Implementation of the classes in header <strstream>.
00015 // WARNING: The classes defined in <strstream> are DEPRECATED.  This
00016 // header is defined in section D.7.1 of the C++ standard, and it
00017 // MAY BE REMOVED in a future standard revision.  You should use the
00018 // header <sstream> instead.
00019 
00020 #include <strstream.h>
00021 #include <algorithm>
00022 #include <new>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <limits.h>
00026 
00027 namespace std
00028 {
00029 
00030 // strstreambuf constructor, destructor.
00031 
00032 strstreambuf::strstreambuf(streamsize initial_capacity)
00033   : _Base(),
00034     _M_alloc_fun(0), _M_free_fun(0),
00035     _M_dynamic(true), _M_frozen(false), _M_constant(false)
00036 {
00037   streamsize n = max(initial_capacity, streamsize(16));
00038 
00039   char* buf = _M_alloc(n);
00040   if (buf) {
00041     setp(buf, buf + n);
00042     setg(buf, buf, buf);
00043   }
00044 }
00045 
00046 strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
00047   : _Base(),
00048     _M_alloc_fun(alloc_f), _M_free_fun(free_f),
00049     _M_dynamic(true), _M_frozen(false), _M_constant(false)
00050 {
00051   streamsize n = 16;
00052 
00053   char* buf = _M_alloc(n);
00054   if (buf) {
00055     setp(buf, buf + n);
00056     setg(buf, buf, buf);
00057   }
00058 }
00059 
00060 strstreambuf::strstreambuf(char* get, streamsize n, char* put)
00061   : _Base(),
00062     _M_alloc_fun(0), _M_free_fun(0),
00063     _M_dynamic(false), _M_frozen(false), _M_constant(false)
00064 {
00065   _M_setup(get, put, n);
00066 }
00067 
00068 strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
00069   : _Base(),
00070     _M_alloc_fun(0), _M_free_fun(0),
00071     _M_dynamic(false), _M_frozen(false), _M_constant(false)
00072 {
00073   _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
00074 }
00075 
00076 strstreambuf::strstreambuf(unsigned char* get, streamsize n,
00077                            unsigned char* put)
00078   : _Base(),
00079     _M_alloc_fun(0), _M_free_fun(0),
00080     _M_dynamic(false), _M_frozen(false), _M_constant(false)
00081 {
00082   _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
00083 }
00084 
00085 strstreambuf::strstreambuf(const char* get, streamsize n)
00086   : _Base(),
00087     _M_alloc_fun(0), _M_free_fun(0),
00088     _M_dynamic(false), _M_frozen(false), _M_constant(true)
00089 {
00090   _M_setup(const_cast<char*>(get), 0, n);
00091 }
00092 
00093 strstreambuf::strstreambuf(const signed char* get, streamsize n)
00094   : _Base(),
00095     _M_alloc_fun(0), _M_free_fun(0),
00096     _M_dynamic(false), _M_frozen(false), _M_constant(true)
00097 {
00098   _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n);
00099 }
00100 
00101 strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
00102   : _Base(),
00103     _M_alloc_fun(0), _M_free_fun(0),
00104     _M_dynamic(false), _M_frozen(false), _M_constant(true)
00105 {
00106   _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n);
00107 }
00108 
00109 strstreambuf::~strstreambuf()
00110 {
00111   if (_M_dynamic && !_M_frozen)
00112     _M_free(eback());
00113 }
00114 
00115 void strstreambuf::freeze(bool frozenflag)
00116 {
00117   if (_M_dynamic)
00118     _M_frozen = frozenflag;
00119 }
00120 
00121 char* strstreambuf::str()
00122 {
00123   freeze(true);
00124   return eback();
00125 }
00126 
00127 int strstreambuf::pcount() const
00128 {
00129   return pptr() ? pptr() - pbase() : 0;
00130 }
00131 
00132 strstreambuf::int_type strstreambuf::overflow(int_type c) {
00133   if (c == traits_type::eof())
00134     return traits_type::not_eof(c);
00135 
00136   // Try to expand the buffer.
00137   if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) {
00138     ptrdiff_t old_size = epptr() - pbase();
00139     ptrdiff_t new_size = max(2 * old_size, ptrdiff_t(1));
00140 
00141     char* buf = _M_alloc(new_size);
00142     if (buf) {
00143       memcpy(buf, pbase(), old_size);
00144 
00145       char* old_buffer = pbase();
00146       bool reposition_get = false;
00147       ptrdiff_t old_get_offset;
00148       if (gptr() != 0) {
00149         reposition_get = true;
00150         old_get_offset = gptr() - eback();
00151       }
00152 
00153       setp(buf, buf + new_size);
00154       pbump(old_size);
00155 
00156       if (reposition_get)
00157         setg(buf, buf + old_get_offset, buf + max(old_get_offset, old_size));
00158 
00159       _M_free(old_buffer);
00160     }
00161   }
00162 
00163   if (pptr() != epptr()) {
00164     *pptr() = c;
00165     pbump(1);
00166     return c;
00167   }
00168   else
00169     return traits_type::eof();
00170 }
00171 
00172 strstreambuf::int_type strstreambuf::pbackfail(int_type c)
00173 {
00174   if (gptr() != eback()) {
00175     if (c == _Traits::eof()) {
00176       gbump(-1);
00177       return _Traits::not_eof(c);
00178     }
00179     else if (c == static_cast<int_type>(gptr()[-1])) {  // KLUDGE
00180       gbump(-1);
00181       return c;
00182     }
00183     else if (!_M_constant) {
00184       gbump(-1);
00185       *gptr() = c;
00186       return c;
00187     }
00188   }
00189 
00190   return _Traits::eof();
00191 }
00192 
00193 strstreambuf::int_type strstreambuf::underflow()
00194 {
00195   if (gptr() == egptr() && pptr() && pptr() > egptr())
00196     setg(eback(), gptr(), pptr());
00197 
00198   if (gptr() != egptr())
00199     return (unsigned char) *gptr();
00200   else
00201     return _Traits::eof();
00202 }
00203 
00204 basic_streambuf<char, char_traits<char> >*
00205 strstreambuf::setbuf(char*, streamsize)
00206 {
00207   return this;
00208 }
00209 
00210 strstreambuf::pos_type
00211 strstreambuf::seekoff(off_type off,
00212                       ios_base::seekdir dir, ios_base::openmode mode)
00213 {
00214   bool do_get = false;
00215   bool do_put = false;
00216 
00217   if ((mode & (ios_base::in | ios_base::out)) ==
00218           (ios_base::in | ios_base::out) &&
00219       (dir == ios_base::beg || dir == ios_base::end))
00220     do_get = do_put = true;
00221   else if (mode & ios_base::in)
00222     do_get = true;
00223   else if (mode & ios_base::out)
00224     do_put = true;
00225 
00226   // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
00227   // area is undefined if there is no get area.
00228   if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
00229     return pos_type(off_type(-1));
00230 
00231   char* seeklow  = eback();
00232   char* seekhigh = epptr() ? epptr() : egptr();
00233 
00234   off_type newoff;
00235   switch(dir) {
00236   case ios_base::beg:
00237     newoff = 0;
00238     break;
00239   case ios_base::end:
00240     newoff = seekhigh - seeklow;
00241     break;
00242   case ios_base::cur:
00243     newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
00244     break;
00245   default:
00246     return pos_type(off_type(-1));
00247   }
00248 
00249   off += newoff;
00250   if (off < 0 || off > seekhigh - seeklow)
00251     return pos_type(off_type(-1));
00252 
00253   if (do_put) {
00254     if (seeklow + off < pbase()) {
00255       setp(seeklow, epptr());
00256       pbump(off);
00257     }
00258     else {
00259       setp(pbase(), epptr());
00260       pbump(off - (pbase() - seeklow));
00261     }
00262   }
00263   if (do_get) {
00264     if (off <= egptr() - seeklow)
00265       setg(seeklow, seeklow + off, egptr());
00266     else if (off <= pptr() - seeklow)
00267       setg(seeklow, seeklow + off, pptr());
00268     else
00269       setg(seeklow, seeklow + off, epptr());
00270   }
00271 
00272   return pos_type(newoff);
00273 }
00274 
00275 strstreambuf::pos_type
00276 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
00277 {
00278   return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
00279 }
00280 
00281 char* strstreambuf::_M_alloc(size_t n)
00282 {
00283   if (_M_alloc_fun)
00284     return static_cast<char*>(_M_alloc_fun(n));
00285   else
00286     return new char[n];
00287 }
00288 
00289 void strstreambuf::_M_free(char* p)
00290 {
00291   if (p)
00292     if (_M_free_fun)
00293       _M_free_fun(p);
00294     else
00295       delete[] p;
00296 }
00297 
00298 void strstreambuf::_M_setup(char* get, char* put, streamsize n)
00299 {
00300   if (get) {
00301     size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
00302 
00303     if (put) {
00304       setg(get, get, put);
00305       setp(put, put + N);
00306     }
00307     else {
00308       setg(get, get, get + N);
00309     }
00310   }
00311 }
00312 
00313 //----------------------------------------------------------------------
00314 // Class istrstream
00315 
00316 istrstream::istrstream(char* s)
00317   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
00318 {
00319   basic_ios<char>::init(&_M_buf);
00320 }
00321 
00322 istrstream::istrstream(const char* s)
00323   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
00324 {
00325   basic_ios<char>::init(&_M_buf);
00326 }
00327 
00328 istrstream::istrstream(char* s, streamsize n)
00329   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
00330 {
00331   basic_ios<char>::init(&_M_buf);
00332 }
00333 
00334 istrstream::istrstream(const char* s, streamsize n)
00335   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
00336 {
00337   basic_ios<char>::init(&_M_buf);
00338 }
00339 
00340 istrstream::~istrstream() {}
00341 
00342 strstreambuf* istrstream::rdbuf() const {
00343   return const_cast<strstreambuf*>(&_M_buf);
00344 }
00345 
00346 char* istrstream::str() { return _M_buf.str(); }
00347 
00348 //----------------------------------------------------------------------
00349 // Class ostrstream
00350 
00351 ostrstream::ostrstream()
00352   : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
00353 {
00354   basic_ios<char>::init(&_M_buf);
00355 }
00356 
00357 ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
00358   : basic_ios<char>(), basic_ostream<char>(0),
00359     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
00360 {
00361   basic_ios<char>::init(&_M_buf);
00362 }
00363 
00364 ostrstream::~ostrstream() {}
00365 
00366 strstreambuf* ostrstream::rdbuf() const
00367 {
00368   return const_cast<strstreambuf*>(&_M_buf);
00369 }
00370 
00371 void ostrstream::freeze(bool freezeflag)
00372 {
00373   _M_buf.freeze(freezeflag);
00374 }
00375 
00376 char* ostrstream::str()
00377 {
00378   return _M_buf.str();
00379 }
00380 
00381 int ostrstream::pcount() const
00382 {
00383   return _M_buf.pcount();
00384 }
00385 
00386 //----------------------------------------------------------------------
00387 // Class strstream
00388 
00389 strstream::strstream()
00390   : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
00391 {
00392   basic_ios<char>::init(&_M_buf);
00393 }
00394 
00395 strstream::strstream(char* s, int n, ios_base::openmode mode)
00396   : basic_ios<char>(), basic_iostream<char>(0),
00397     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
00398 {
00399   basic_ios<char>::init(&_M_buf);
00400 }
00401 
00402 strstream::~strstream() {}
00403 
00404 strstreambuf* strstream::rdbuf() const
00405 {
00406   return const_cast<strstreambuf*>(&_M_buf);
00407 }
00408 
00409 void strstream::freeze(bool freezeflag)
00410 {
00411   _M_buf.freeze(freezeflag);
00412 }
00413 
00414 int strstream::pcount() const
00415 {
00416   return _M_buf.pcount();
00417 }
00418 
00419 char* strstream::str()
00420 {
00421   return _M_buf.str();
00422 }
00423 
00424 } // namespace std
00425 
00426 // Local Variables:
00427 // mode:C++
00428 // End:

Generated at Tue May 1 16:28:40 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001