00001 // String based streams -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 // 00031 // ISO C++ 14882: 27.7 String-based streams 00032 // 00033 00034 /** @file sstream 00035 * This is a Standard C++ Library header. You should @c #include this header 00036 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 00037 */ 00038 00039 #ifndef _CPP_SSTREAM 00040 #define _CPP_SSTREAM 1 00041 00042 #pragma GCC system_header 00043 00044 #include <istream> 00045 #include <ostream> 00046 00047 namespace std 00048 { 00049 // [27.7.1] template class basic_stringbuf 00050 /** 00051 * @brief The actual work of input and output (for std::string). 00052 * 00053 * This class associates either or both of its input and output sequences 00054 * with a sequence of characters, which can be initialized from, or made 00055 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 00056 * 00057 * For this class, open modes (of type @c ios_base::openmode) have 00058 * @c in set if the input sequence can be read, and @c out set if the 00059 * output sequence can be written. 00060 */ 00061 template<typename _CharT, typename _Traits, typename _Alloc> 00062 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 00063 { 00064 public: 00065 // Types: 00066 typedef _CharT char_type; 00067 typedef _Traits traits_type; 00068 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 00069 // 251. basic_stringbuf missing allocator_type 00070 typedef _Alloc allocator_type; 00071 #endif 00072 typedef typename traits_type::int_type int_type; 00073 typedef typename traits_type::pos_type pos_type; 00074 typedef typename traits_type::off_type off_type; 00075 00076 //@{ 00077 /** 00078 * @if maint 00079 * @doctodo 00080 * @endif 00081 */ 00082 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 00083 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 00084 typedef typename __string_type::size_type __size_type; 00085 //@} 00086 00087 protected: 00088 // Data Members: 00089 /** 00090 * @if maint 00091 * @doctodo 00092 * @endif 00093 */ 00094 __string_type _M_string; 00095 00096 public: 00097 // Constructors: 00098 /** 00099 * @brief Starts with an empty string buffer. 00100 * @param mode Whether the buffer can read, or write, or both. 00101 * 00102 * The default constructor initializes the parent class using its 00103 * own default ctor. 00104 */ 00105 explicit 00106 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 00107 : __streambuf_type(), _M_string() 00108 { _M_stringbuf_init(__mode); } 00109 00110 /** 00111 * @brief Starts with an existing string buffer. 00112 * @param str A string to copy as a starting buffer. 00113 * @param mode Whether the buffer can read, or write, or both. 00114 * 00115 * This constructor initializes the parent class using its 00116 * own default ctor. 00117 */ 00118 explicit 00119 basic_stringbuf(const __string_type& __str, 00120 ios_base::openmode __mode = ios_base::in | ios_base::out) 00121 : __streambuf_type(), _M_string(__str.data(), __str.size()) 00122 { _M_stringbuf_init(__mode); } 00123 00124 // Get and set: 00125 /** 00126 * @brief Copying out the string buffer. 00127 * @return A copy of one of the underlying sequences. 00128 * 00129 * "If the buffer is only created in input mode, the underlying 00130 * character sequence is equal to the input sequence; otherwise, it 00131 * is equal to the output sequence." [27.7.1.2]/1 00132 */ 00133 __string_type 00134 str() const 00135 { 00136 if (_M_mode & ios_base::out) 00137 { 00138 // This is the deal: _M_string.size() is a value that 00139 // represents the size of the initial string that makes 00140 // _M_string, and may not be the correct size of the 00141 // current stringbuf internal buffer. 00142 __size_type __len = _M_string.size(); 00143 if (_M_out_end > _M_out_beg) 00144 __len = max(__size_type(_M_out_end - _M_out_beg), __len); 00145 return __string_type(_M_out_beg, _M_out_beg + __len); 00146 } 00147 else 00148 return _M_string; 00149 } 00150 00151 /** 00152 * @brief Setting a new buffer. 00153 * @param s The string to use as a new sequence. 00154 * 00155 * Deallocates any previous stored sequence, then copies @a s to 00156 * use as a new one. 00157 */ 00158 void 00159 str(const __string_type& __s) 00160 { 00161 // Cannot use _M_string = __s, since v3 strings are COW. 00162 _M_string.assign(__s.data(), __s.size()); 00163 _M_stringbuf_init(_M_mode); 00164 } 00165 00166 protected: 00167 // Common initialization code for both ctors goes here. 00168 /** 00169 * @if maint 00170 * @doctodo 00171 * @endif 00172 */ 00173 void 00174 _M_stringbuf_init(ios_base::openmode __mode) 00175 { 00176 // _M_buf_size is a convenient alias for "what the streambuf 00177 // thinks the allocated size of the string really is." This is 00178 // necessary as ostringstreams are implemented with the 00179 // streambufs having control of the allocation and 00180 // re-allocation of the internal string object, _M_string. 00181 _M_buf_size = _M_string.size(); 00182 00183 // NB: Start ostringstream buffers at 512 bytes. This is an 00184 // experimental value (pronounced "arbitrary" in some of the 00185 // hipper english-speaking countries), and can be changed to 00186 // suit particular needs. 00187 _M_buf_size_opt = 512; 00188 _M_mode = __mode; 00189 if (_M_mode & (ios_base::ate | ios_base::app)) 00190 _M_really_sync(0, _M_buf_size); 00191 else 00192 _M_really_sync(0, 0); 00193 } 00194 00195 // Overridden virtual functions: 00196 // [documentation is inherited] 00197 virtual int_type 00198 underflow() 00199 { 00200 if (_M_in_cur && _M_in_cur < _M_in_end) 00201 return traits_type::to_int_type(*gptr()); 00202 else 00203 return traits_type::eof(); 00204 } 00205 00206 // [documentation is inherited] 00207 virtual int_type 00208 pbackfail(int_type __c = traits_type::eof()); 00209 00210 // [documentation is inherited] 00211 virtual int_type 00212 overflow(int_type __c = traits_type::eof()); 00213 00214 /** 00215 * @brief Manipulates the buffer. 00216 * @param s Pointer to a buffer area. 00217 * @param n Size of @a s. 00218 * @return @c this 00219 * 00220 * If no buffer has already been created, and both @a s and @a n are 00221 * non-zero, then @c s is used as a buffer; see 00222 * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 00223 * for more. 00224 */ 00225 virtual __streambuf_type* 00226 setbuf(char_type* __s, streamsize __n) 00227 { 00228 if (__s && __n) 00229 { 00230 _M_string = __string_type(__s, __n); 00231 _M_really_sync(0, 0); 00232 } 00233 return this; 00234 } 00235 00236 // [documentation is inherited] 00237 virtual pos_type 00238 seekoff(off_type __off, ios_base::seekdir __way, 00239 ios_base::openmode __mode = ios_base::in | ios_base::out); 00240 00241 // [documentation is inherited] 00242 virtual pos_type 00243 seekpos(pos_type __sp, 00244 ios_base::openmode __mode = ios_base::in | ios_base::out); 00245 00246 // Internal function for correctly updating the internal buffer 00247 // for a particular _M_string, due to initialization or 00248 // re-sizing of an existing _M_string. 00249 // Assumes: contents of _M_string and internal buffer match exactly. 00250 // __i == _M_in_cur - _M_in_beg 00251 // __o == _M_out_cur - _M_out_beg 00252 /** 00253 * @if maint 00254 * @doctodo 00255 * @endif 00256 */ 00257 virtual int 00258 _M_really_sync(__size_type __i, __size_type __o) 00259 { 00260 char_type* __base = const_cast<char_type*>(_M_string.data()); 00261 bool __testin = _M_mode & ios_base::in; 00262 bool __testout = _M_mode & ios_base::out; 00263 __size_type __len = _M_string.size(); 00264 00265 _M_buf = __base; 00266 if (__testin) 00267 this->setg(__base, __base + __i, __base + __len); 00268 if (__testout) 00269 { 00270 this->setp(__base, __base + __len); 00271 _M_out_cur += __o; 00272 } 00273 return 0; 00274 } 00275 }; 00276 00277 00278 // [27.7.2] Template class basic_istringstream 00279 /** 00280 * @brief Controlling input for std::string. 00281 * 00282 * This class supports reading from objects of type std::basic_string, 00283 * using the inherited functions from std::basic_istream. To control 00284 * the associated sequence, an instance of std::basic_stringbuf is used, 00285 * which this page refers to as @c sb. 00286 */ 00287 template<typename _CharT, typename _Traits, typename _Alloc> 00288 class basic_istringstream : public basic_istream<_CharT, _Traits> 00289 { 00290 public: 00291 // Types: 00292 typedef _CharT char_type; 00293 typedef _Traits traits_type; 00294 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 00295 // 251. basic_stringbuf missing allocator_type 00296 typedef _Alloc allocator_type; 00297 #endif 00298 typedef typename traits_type::int_type int_type; 00299 typedef typename traits_type::pos_type pos_type; 00300 typedef typename traits_type::off_type off_type; 00301 00302 // Non-standard types: 00303 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00304 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00305 typedef basic_istream<char_type, traits_type> __istream_type; 00306 00307 private: 00308 /** 00309 * @if maint 00310 * @doctodo 00311 * @endif 00312 */ 00313 __stringbuf_type _M_stringbuf; 00314 00315 public: 00316 // Constructors: 00317 /** 00318 * @brief Default constructor starts with an empty string buffer. 00319 * @param mode Whether the buffer can read, or write, or both. 00320 * 00321 * @c ios_base::in is automatically included in @a mode. 00322 * 00323 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 00324 * class initializer. Does not allocate any buffer. 00325 * 00326 * @if maint 00327 * That's a lie. We initialize the base class with NULL, because the 00328 * string class does its own memory management. 00329 * @endif 00330 */ 00331 explicit 00332 basic_istringstream(ios_base::openmode __mode = ios_base::in) 00333 : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in) 00334 { this->init(&_M_stringbuf); } 00335 00336 /** 00337 * @brief Starts with an existing string buffer. 00338 * @param str A string to copy as a starting buffer. 00339 * @param mode Whether the buffer can read, or write, or both. 00340 * 00341 * @c ios_base::in is automatically included in @a mode. 00342 * 00343 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 00344 * to the base class initializer. 00345 * 00346 * @if maint 00347 * That's a lie. We initialize the base class with NULL, because the 00348 * string class does its own memory management. 00349 * @endif 00350 */ 00351 explicit 00352 basic_istringstream(const __string_type& __str, 00353 ios_base::openmode __mode = ios_base::in) 00354 : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in) 00355 { this->init(&_M_stringbuf); } 00356 00357 /** 00358 * @brief The destructor does nothing. 00359 * 00360 * The buffer is deallocated by the stringbuf object, not the 00361 * formatting stream. 00362 */ 00363 ~basic_istringstream() 00364 { } 00365 00366 // Members: 00367 /** 00368 * @brief Accessing the underlying buffer. 00369 * @return The current basic_stringbuf buffer. 00370 * 00371 * This hides both signatures of std::basic_ios::rdbuf(). 00372 */ 00373 __stringbuf_type* 00374 rdbuf() const 00375 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00376 00377 /** 00378 * @brief Copying out the string buffer. 00379 * @return @c rdbuf()->str() 00380 */ 00381 __string_type 00382 str() const 00383 { return _M_stringbuf.str(); } 00384 00385 /** 00386 * @brief Setting a new buffer. 00387 * @param s The string to use as a new sequence. 00388 * 00389 * Calls @c rdbuf()->str(s). 00390 */ 00391 void 00392 str(const __string_type& __s) 00393 { _M_stringbuf.str(__s); } 00394 }; 00395 00396 00397 // [27.7.3] Template class basic_ostringstream 00398 /** 00399 * @brief Controlling output for std::string. 00400 * 00401 * This class supports writing to objects of type std::basic_string, 00402 * using the inherited functions from std::basic_ostream. To control 00403 * the associated sequence, an instance of std::basic_stringbuf is used, 00404 * which this page refers to as @c sb. 00405 */ 00406 template <typename _CharT, typename _Traits, typename _Alloc> 00407 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 00408 { 00409 public: 00410 // Types: 00411 typedef _CharT char_type; 00412 typedef _Traits traits_type; 00413 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 00414 // 251. basic_stringbuf missing allocator_type 00415 typedef _Alloc allocator_type; 00416 #endif 00417 typedef typename traits_type::int_type int_type; 00418 typedef typename traits_type::pos_type pos_type; 00419 typedef typename traits_type::off_type off_type; 00420 00421 // Non-standard types: 00422 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00423 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00424 typedef basic_ostream<char_type, traits_type> __ostream_type; 00425 00426 private: 00427 /** 00428 * @if maint 00429 * @doctodo 00430 * @endif 00431 */ 00432 __stringbuf_type _M_stringbuf; 00433 00434 public: 00435 // Constructors/destructor: 00436 /** 00437 * @brief Default constructor starts with an empty string buffer. 00438 * @param mode Whether the buffer can read, or write, or both. 00439 * 00440 * @c ios_base::out is automatically included in @a mode. 00441 * 00442 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 00443 * class initializer. Does not allocate any buffer. 00444 * 00445 * @if maint 00446 * That's a lie. We initialize the base class with NULL, because the 00447 * string class does its own memory management. 00448 * @endif 00449 */ 00450 explicit 00451 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 00452 : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out) 00453 { this->init(&_M_stringbuf); } 00454 00455 /** 00456 * @brief Starts with an existing string buffer. 00457 * @param str A string to copy as a starting buffer. 00458 * @param mode Whether the buffer can read, or write, or both. 00459 * 00460 * @c ios_base::out is automatically included in @a mode. 00461 * 00462 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 00463 * to the base class initializer. 00464 * 00465 * @if maint 00466 * That's a lie. We initialize the base class with NULL, because the 00467 * string class does its own memory management. 00468 * @endif 00469 */ 00470 explicit 00471 basic_ostringstream(const __string_type& __str, 00472 ios_base::openmode __mode = ios_base::out) 00473 : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out) 00474 { this->init(&_M_stringbuf); } 00475 00476 /** 00477 * @brief The destructor does nothing. 00478 * 00479 * The buffer is deallocated by the stringbuf object, not the 00480 * formatting stream. 00481 */ 00482 ~basic_ostringstream() 00483 { } 00484 00485 // Members: 00486 /** 00487 * @brief Accessing the underlying buffer. 00488 * @return The current basic_stringbuf buffer. 00489 * 00490 * This hides both signatures of std::basic_ios::rdbuf(). 00491 */ 00492 __stringbuf_type* 00493 rdbuf() const 00494 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00495 00496 /** 00497 * @brief Copying out the string buffer. 00498 * @return @c rdbuf()->str() 00499 */ 00500 __string_type 00501 str() const 00502 { return _M_stringbuf.str(); } 00503 00504 /** 00505 * @brief Setting a new buffer. 00506 * @param s The string to use as a new sequence. 00507 * 00508 * Calls @c rdbuf()->str(s). 00509 */ 00510 void 00511 str(const __string_type& __s) 00512 { _M_stringbuf.str(__s); } 00513 }; 00514 00515 00516 // [27.7.4] Template class basic_stringstream 00517 /** 00518 * @brief Controlling input and output for std::string. 00519 * 00520 * This class supports reading from and writing to objects of type 00521 * std::basic_string, using the inherited functions from 00522 * std::basic_iostream. To control the associated sequence, an instance 00523 * of std::basic_stringbuf is used, which this page refers to as @c sb. 00524 */ 00525 template <typename _CharT, typename _Traits, typename _Alloc> 00526 class basic_stringstream : public basic_iostream<_CharT, _Traits> 00527 { 00528 public: 00529 // Types: 00530 typedef _CharT char_type; 00531 typedef _Traits traits_type; 00532 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 00533 // 251. basic_stringbuf missing allocator_type 00534 typedef _Alloc allocator_type; 00535 #endif 00536 typedef typename traits_type::int_type int_type; 00537 typedef typename traits_type::pos_type pos_type; 00538 typedef typename traits_type::off_type off_type; 00539 00540 // Non-standard Types: 00541 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00542 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00543 typedef basic_iostream<char_type, traits_type> __iostream_type; 00544 00545 private: 00546 /** 00547 * @if maint 00548 * @doctodo 00549 * @endif 00550 */ 00551 __stringbuf_type _M_stringbuf; 00552 00553 public: 00554 // Constructors/destructors 00555 /** 00556 * @brief Default constructor starts with an empty string buffer. 00557 * @param mode Whether the buffer can read, or write, or both. 00558 * 00559 * Initializes @c sb using @c mode, and passes @c &sb to the base 00560 * class initializer. Does not allocate any buffer. 00561 * 00562 * @if maint 00563 * That's a lie. We initialize the base class with NULL, because the 00564 * string class does its own memory management. 00565 * @endif 00566 */ 00567 explicit 00568 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 00569 : __iostream_type(NULL), _M_stringbuf(__m) 00570 { this->init(&_M_stringbuf); } 00571 00572 /** 00573 * @brief Starts with an existing string buffer. 00574 * @param str A string to copy as a starting buffer. 00575 * @param mode Whether the buffer can read, or write, or both. 00576 * 00577 * Initializes @c sb using @a str and @c mode, and passes @c &sb 00578 * to the base class initializer. 00579 * 00580 * @if maint 00581 * That's a lie. We initialize the base class with NULL, because the 00582 * string class does its own memory management. 00583 * @endif 00584 */ 00585 explicit 00586 basic_stringstream(const __string_type& __str, 00587 ios_base::openmode __m = ios_base::out | ios_base::in) 00588 : __iostream_type(NULL), _M_stringbuf(__str, __m) 00589 { this->init(&_M_stringbuf); } 00590 00591 /** 00592 * @brief The destructor does nothing. 00593 * 00594 * The buffer is deallocated by the stringbuf object, not the 00595 * formatting stream. 00596 */ 00597 ~basic_stringstream() 00598 { } 00599 00600 // Members: 00601 /** 00602 * @brief Accessing the underlying buffer. 00603 * @return The current basic_stringbuf buffer. 00604 * 00605 * This hides both signatures of std::basic_ios::rdbuf(). 00606 */ 00607 __stringbuf_type* 00608 rdbuf() const 00609 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00610 00611 /** 00612 * @brief Copying out the string buffer. 00613 * @return @c rdbuf()->str() 00614 */ 00615 __string_type 00616 str() const 00617 { return _M_stringbuf.str(); } 00618 00619 /** 00620 * @brief Setting a new buffer. 00621 * @param s The string to use as a new sequence. 00622 * 00623 * Calls @c rdbuf()->str(s). 00624 */ 00625 void 00626 str(const __string_type& __s) 00627 { _M_stringbuf.str(__s); } 00628 }; 00629 } // namespace std 00630 00631 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT 00632 # define export 00633 #endif 00634 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS 00635 # include <bits/sstream.tcc> 00636 #endif 00637 00638 #endif