Whole document tree strstream.ccGo 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 ![]() |