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 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
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 
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   
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])) {  
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   
00257   
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 
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 
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 
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 } 
00455 
00456 
00457 
00458