00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025  
00026 
00027 
00028 
00029 
00030 
00031 
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 
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   
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   
00245   
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 
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 
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 } 
00404 
00405 
00406 
00407