Whole document tree
    

Whole document tree

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

Generated on Mon Apr 8 03:11:46 2002 for libstdc++-v3 Source by doxygen1.2.15