w_compat_strstream.cpp

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

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7