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